Disegna con la tua CPU


289

Mi sono imbattuto in un articolo in cui gli studenti hanno utilizzato il traffico di rete per disegnare la loro università sul grafico IPv6 del paese . [Immagine]

Il tuo obiettivo è semplice da dire, ma difficile da implementare. Disegna il testo MAIL (in quanto è una delle poche parole che possono essere lette su un grafico 1D) sul grafico della CPU.

Dovrebbe assomigliare a qualcosa di simile a questo:

Risultato

Elaborando un po 'di più su ciò che si qualifica:

  • Non è necessario che il codice sia multipiattaforma (quindi non avrai bisogno di API sconosciute per gestire).
  • È possibile acquisirlo in qualsiasi utilità generale di utilizzo della CPU che si possiede.
  • Il grafico sembra un po 'peggio su una macchina diversa: questa volta mi fido di te.
  • L'utilizzo della CPU di base% deve essere continuo, quindi se si genera un'onda casuale e si evidenzia qualcosa che assomiglia alla parola MAIL, è ovviamente barare.
  • Puoi scegliere il carico massimo da usare, ma deve essere abbastanza sostanzioso da vederlo chiaramente.
  • È necessario seguire la linearità dell'esempio. (Per M è simile al seguente:% base, quindi aumento improvviso al massimo specificato, riduzione graduale a un% inferiore, ritorno al massimo e calo improvviso al% base.)
  • Se è illeggibile, gli elettori lo noteranno dopo tutto.

Si applicano scappatoie standard. Pubblica anche le immagini!


9
Non vedo più un motivo per il voto vicino. Personalmente trovo questa una sfida divertente, anche se un po 'specifica per il sistema.
Seequ,

6
Il problema che vedo con il codice golf è giudicare quanto leggibile sia abbastanza leggibile. Se riesci a pensare a un modo per specificarlo in modo obiettivo, ciò migliorerebbe notevolmente la sfida, ma è comunque una bella idea!
Martin Ender,

3
è davvero la stessa della tua foto, ma ti garantisco che se non la metti in parole, la gente interpreterà "disegna MAIL" in modo molto libero.
Martin Ender,

33
+1, è così assurdo che mi sono quasi ridacchiato a morte ... "questa è follia ..." "Follia .. QUESTO È CODEGOLF !!!"
vaxquis,

5
Questa è una domanda fantastica . Vorrei essere abbastanza intelligente da partecipare. Non importa, sono interessato alle soluzioni creative di altre persone: P
Chris Cirefice,

Risposte:


117

Python, 143

from time import*
while 1:
 sleep((ord('00012345654321000~~~D:6300036:D~~~000~~~000DDDD~~~~~'[int(time())%52])-48)*0.001);x=10**5
 while x:x-=1

Ogni carattere della stringa corrisponde a un secondo di attività, dal carattere ASCII 0(carico massimo) fino a ~(carico molto leggero). Il programma viene eseguito su un ciclo sincronizzato nel tempo, quindi è possibile eseguire più istanze per risultati migliori.

Ho usato Python 2.7.6 su OS X con un Intel Core i7, ma dovrebbe funzionare su altri computer con un po 'di ottimizzazione (regolare il 0.001). La schermata seguente è stata scattata con un'attività in background significativa.

MAIL

Aggiornamento: sono stato in grado di produrre un grafico più chiaro con time()/10una frequenza di aggiornamento inferiore:

MAIL

E infine, ecco una versione più giocata ( 123 byte ) e il suo risultato :

from time import*
while 1:
 sleep((ord('002464200~~A5005A~~00~~00DDD~~'[int(time()/2)%30])-48)*0.001);x=10**5
 while x:x-=1

250

Python, 358 281 268 221 194 byte

Monochrome è così l'anno scorso. Questo utilizza più processi e syscall per ottenere due grafici a colori della CPU!

import os,time
A='%-99o'%int('t12q2lxqkap48euoej9429cstbnazl63ubyryteo49u',36)
for i in'0123456':
 t=os.fork()
 while t<1:T=int(time.time())%50;(time.sleep,(id,os.urandom)[i<A[T+49]])[i<A[T]](1)

Uscita da Activity Monitor (OS X 10.9):

Grafico di carico della CPU di Activity Monitor Grafico cronologico CPU Monitor attività

Si ripete sul grafico della cronologia della CPU

Uscita da MenuMeters:

Uscita MenuMeters

Tutti gli output sono stati generati con una velocità di aggiornamento di 1 s. Non sono state eseguite attività in background significative, sebbene questo output superi abbastanza facilmente qualsiasi attività CPU a thread singolo.

Questo codice presuppone che tu abbia 8 core. Dovrebbe essere abbastanza facile da modificare per meno / più. È portabile su sistemi Linux / UNIX (sebbene sia stato testato solo su OS X) e dovrebbe produrre lo stesso output bicolore per qualsiasi monitor CPU in grado di distinguere il tempo utente dalla CPU del sistema.

Fondamentalmente, funziona eliminando sette processi, ognuno dei quali sceglierà di passare 1 secondo a dormire, girare in modalità utente o girare il kernel. La rotazione in modalità kernel viene ottenuta richiedendo grandi quantità di dati /dev/urandom, il che costringe il driver /dev/urandoma spendere molti cicli di CPU "di sistema".

EDITED [07/21]: abbreviato in modo significativo utilizzando fork()invece di multiprocessing.Process( /dev/urandomfunziona solo su sistemi * NIX in modo da non ridurre la portabilità). Si noti tuttavia che il programma ora genera attività in background ; potrebbe essere necessario killall Python(o simile) per sbarazzarsi dei mangiatori di CPU.


Non ho resistito all'implementazione di qualche altra lettera. Ho ricevuto 16 lettere, più alcuni simboli:

~ /._ PIN ANCHO ... ... VY

L'alfabeto completo è "ACDFHILMNOPTUVWY", con simboli "._ ~ / \". Probabilmente ci sono molti più personaggi che possono essere rappresentati.

Codice completamente non golfato per le lettere extra:

from time import*
from multiprocessing import*

chars6 = {
'A': ('123456654321',
      '000123321000'),
'C': ('344556666666',
      '321110000000'),
'D': ('666666655443',
      '000000011123'),
'F': ('66666666666666',
      '00002222244444'),
'H': ('666664444466666',
      '000002222200000'),
'I': ('66666',
      '00000'),
'L': ('666662222222',
      '000000000000'),
'M': ('6665544334455666',
      '0004321001234000'),
'N': ('66665544336666',
      '00003322110000'),
'O': ('3445556666555443',
      '3221110000111223'),
'P': ('666666666555',
      '000003333444'),
'T': ('777776666677777',
      '444440000044444'),
'U': ('6666322236666',
      '4211000001124'),
'V': ('66654322345666',
      '33321000012333'),
'W': ('66542466424566',
      '43210133101234'),
'Y': ('66665433456666',
      '44333000033344'),
'_': ('1111111111',
      '0000000000'),
' ': ('000',
      '000'),
'.': ('12221',
      '10001'),
'~': ('44445544334444',
      '11223322112233'),
'/': ('2234566',
      '0012344'),
'\\': ('6654322',
       '4432100'),
}

s = 'ANCHOVY '
A = '000'.join(chars6[t][0] for t in s)
B = '000'.join(chars6[t][1] for t in s)

t=time()
f=open('/dev/urandom')
def F(n):
 while 1:T=int(time()-t)%len(A);[sleep,[].count,lambda x:f.read(4**9)][(n<int(A[T]))+(n<int(B[T]))](1)
for i in range(7):Process(target=F,args=(i,)).start()
F(7)

34
+1 per dare alle lettere più definizione usando 2 colori
DustinDavis,

4
E +1 per la creazione di lettere basate sul tavolo
GreenAsJade, l'

1
La A potrebbe infatti essere resa correttamente (con un foro) con 4 fili. Dovrebbe impostare alcuni colori del monitor CPU in modo che coincidano però.
Ruslan,

@Ruslan: a quale monitor CPU stai pensando? Il mio monitor mostra solo un grafico aggregato, con 0 <= sistema <= utente <= 100 in ciascun punto (il che rende "buchi" impossibili AFAIK).
nneonneo,

1
@nneonneo Intendo monitor simili ai tuoi. Vedere questa immagine . Qui se cambiamo blu in verde e rosso e viola in bianco, otterremo una bella "A" con buchi.
Ruslan,

133

C (Intel Core Duo + OS X / Darwin), 248 byte

#include <unistd.h>
#include <mach/mach_time.h>
#define M mach_absolute_time()
main(){char*s="JJJIHGFGHIJJJ@BDFHJJJHFDB@JJJJ@JJJJBBBBBBB";uint64_t i,t,y=1;for(;*s;s++){
for(i=40;i;i--){for(t=M+(*s&15)*9090909;t>M;)y*=7;usleep((11-(*s&15))*9091);}}}

Questo codice è portatile quanto la Grande Piramide di Cheope. Mi dispiace per quello. I valori restituiti mach_absolute_time()dipendono dall'hardware, ma sulla mia macchina il valore aumenta di circa una volta per nanosecondo.

Ecco il risultato:

La parola "MAIL" mostrata nel mio grafico cronologico della CPU

Esistono due grafici perché il processore ha due core. Ho impostato il carico massimo della CPU a circa il 90% perché il processo può passare da un core all'altro ogni volta che chiamo usleep(). Con un carico del 100%, il processo è incatenato a un core e i risultati sono illeggibili ( vedi questo, per esempio )


1
Buon lavoro! Questo sembra molto interessante. Potresti per favore pubblicare una piccola spiegazione del codice? :)
duci9y

1
vedo le parentesi graffe. perché ci sono parentesi graffe nei loop for? puoi mettere addormentato nel secondo per l'ultimo blocco del loop. penso che puoi giocare a golf un po 'più facilmente.
Bebe,

Non potresti mettere la dichiarazione e l'inizializzazione delle uint64_tvariabili nell'intestazione del forciclo seguente ?
Joey,

74
+1: "Questo codice è portatile come la Grande Piramide di Cheope"
Uwe Keim

@Olyly no, le variabili C devono essere dichiarate all'inizio di un blocco. inserendolo nel blocco di inizializzazione di for genererà un errore. ovviamente si applica solo a <C99
bebe

102

Rubino, 150 caratteri

a=(0..15).map{|i|[0.9-3*i*=0.02,i]}
[9,*a[0,11],*(z=a.reverse)[5,11],11,*z,*a,2,11,6,*[0.2]*9].map{|x,y|c=Time.now
1until Time.now-c>x/3
sleep y||x%3}

Finora non è così breve, ma secondo me l'output è piuttosto carino, quindi ho pensato di pubblicarlo comunque. Come con la maggior parte delle altre soluzioni, potrebbe essere necessario bloccare il processo Ruby su un determinato core prefissandolo con taskset -c $core.

Il codice è una semplice combinazione di rotazione / sospensione per un certo periodo di tempo, che dovrebbe renderlo in qualche modo portatile. I gradienti uniformi vengono creati variando il rapporto tra tempo di rotazione / sonno.

MAIL monitor CPU scritto

Abbassare la frequenza di campionamento della CPU rende i bordi un po 'migliori:

Bassa frequenza di campionamento

Aggiungendo qualche altra lettera all'alfabeto ( AILMNUVWsono in qualche modo riconoscibili), possiamo anche scrivere alcune altre parole:

MAMMA, MAW, VILLAIN

Queste immagini sono state generate con il seguente codice:

def gradient num_samples, direction, base = 0.3, increment = 0.02, scale = 1
    range = [*0..num_samples]

    samples = case direction
        when :up then range.reverse
        when :down then range
        when :updown then range.reverse + range
        when :downup then range + range.reverse
    end

    samples.map{|i|
        i *= increment
        [base - scale * i, i]
    }
end

# letters are defined as a series of pairs of (spin-time, sleep-time)
# with the time in seconds
THIN_A = gradient(15, :updown, 0.2, 0.2/15)
A = gradient(15, :updown)
I = 2,0
L = 1.5,0, [[0.1,0.2]]*9
M = 2,0, gradient(9, :downup), 2,0
N = 1,0, gradient(9, :down), 2,0
U = 1,0, gradient(9, :downup, 0.1, 0.03, 0.1), 1,0
V = 0.5,0, gradient(12, :downup, 0.25, 0.02), 0.5,0
W = 0.5,0, [gradient(12, :downup, 0.25, 0.02)]*2, 0.5,0

[A,I,L,M,N,U,V,W].map{|i|
    # add 2 second pause after each letter
    i + [0,2]
}.flatten.each_slice(2){|x,y|
    # spin, then sleep
    c = Time.now
    1 until Time.now-c > x
    sleep y
}

È possibile trovare parole che possono essere scritte con le lettere implementate

grep -E '^[aijlmnuvw]+$' /usr/share/dict/words 

4
+1 per l'estensione in più parole!
Chris Cirefice,

Avresti potuto creare la parola "alluminio".
Oliver Daugherty-Long

@ OliverDaugherty-Long alluminio *
TuxCrafting

1
@ TùxCräftîñg L'alluminio è una variante ortografica che ha una lettera in più, ed è la parola più lunga che riesco a pensare che funzioni.
Oliver Daugherty-Long,

48

Python, su Intel Pentium 4 3.0Ghz, 180 166 145 141 138 byte

Chiama con taskset -c 0 python cpu_graph_drawer.py.

taskset è necessario per limitare il processo in modo da utilizzare solo una CPU / core (hyperthreading nel mio caso).

from time import*;c=clock
a=[(3,.8),(3,5),(4,5),(1.3,5),(1.3,0)]
a.extend([(.1,.2)]*10)
for x,y in a:
    t=c()
    while c()-t<x:pass
    sleep(y)

Il risultato non è eccezionale. Questo con tasket -c 1


9
Mi piacerebbe vederlo con un monitor CPU che non leviga le curve ...
Szabolcs

1
Anch'io, ma non mi va di scrivere un grafico di utilizzo della CPU intuitivo ed gnome-system-monitorè l'unica cosa che conosco. Hai delle alternative che funzionerebbero con LMDE Cinnamon?
user80551

Abilita "Disegna CPU come grafico ad area in pila" e imposta tutti i colori sul nero.
Tejas Kale,

@TejasKale Le linee sarebbero ancora curve.
user80551

A proposito: puoi giocare a golf un sacco di caratteri usando a=[...]+[(.1,.2)]*10invece di .extend.
nneonneo,

46

Java 8, 482 caratteri

Ogni carattere nella stringa indica il numero di thread che verranno utilizzati. Immagine presa su Intel Core i3 (2 core / 4 thread).

risultato

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Mail{
public static void main(String[] args) throws InterruptedException{
Thread.sleep(15000);
for(char c:"123432234321000012343210000444000044441111111".toCharArray()){
ExecutorService executorService = Executors.newScheduledThreadPool(4);
for(int i=1;i<c-48;i++)executorService.execute(()->{while(!Thread.interrupted());});
Thread.sleep(1500);
executorService.shutdownNow();
}}}

Modifica : più versione golf (322 caratteri), stessa funzionalità:

import java.util.concurrent.*;
class M{
public static void main(String[]a)throws Exception{
for(int c:"123432234321000012343210000444000044441111111".toCharArray()){
ExecutorService s=Executors.newFixedThreadPool(4);
while(c>48){c--;s.execute(()->{while(!Thread.interrupted());});}
Thread.sleep(1500);
s.shutdownNow();
}}}

1
C'è un segno meno che lì interpretato come HTML e incasinato la formattazione.
David Conrad,

Le prossime due righe di @ValekHalfHeart dovrebbero spiegarlo. Executor è un thread (task manager asincrono) che esegue task (s) (loop qui) fino all'interruzione. Dopo averlo creato, il thread principale attende 1,5 secondi e quindi interrompe tutte le attività.
PTwr

45
Aprendo semplicemente Eclipse, il mio grafico della CPU ha scritto "Simple Mail Transfer Protocol".
Lolesque,

21

C, 78 byte

Non hai mai detto che non potremmo accettare l'input dell'utente, quindi ..

#include <unistd.h>
int main(){int x=0;for(;x<1<<26;++x);read(0,&x,1);main();}

Questo programma legge dallo standard in e ogni volta che legge un carattere esegue una CPU gratuita che spreca per il loop, quindi chiama di nuovo main. Puoi controllare la quantità di tempo della CPU che utilizza inviando spam al tasto invio a velocità diverse.

Ho eseguito questo su un Intel i3 4130T, che è un processore ragionevolmente nuovo. Ma il tuo chilometraggio può variare, se utilizza più o meno tempo della CPU di quanto sia pratico per te osservare, prova a giocare con la quantità di spostamento nel loop di ritardo.

Il mio programma è fantastico perché:

  • è principalmente multipiattaforma, dovrebbe funzionare con pochissimi armeggi su qualsiasi * nix
  • sconfigge la domanda
  • grande gioco di fine gioco

Dopo alcuni tentativi ho prodotto un grafico simile al seguente:Grafico della CPU


Aiuta a limitarlo a un core della CPU con tasket, a.la. taskset -c 1 [file]
Wug,

2
Non vedo nulla nei requisiti del problema che dice che i nostri invii verranno invocati comeyes | [program]
Wug


1
"ottimo gioco di fine gioco" mi ha reso duro. +1
Christoph,

1
Questa risposta è troppo buona, però, le lacune sono dannatamente xD!
Magic Octopus Urn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.