Dessine avec ton CPU

289

Je suis tombé sur un article dans lequel des étudiants utilisaient le trafic réseau pour dessiner leur université sur le graphique IPv6 du pays . [image]

Votre objectif est simple à dire, mais difficile à mettre en œuvre. Dessinez le texte MAIL (car il s’agit de l’un des rares mots pouvant être lus sur un graphique 1D) sur le graphique de la CPU.

Ça devrait ressembler a quelque chose comme ca:

Résultat

En élaborant un peu plus sur ce qui est admissible:

  • Le code n'a pas besoin d'être multiplate-forme (vous n'aurez donc pas besoin d'API inconnues pour y faire face).
  • Vous pouvez le capturer dans n'importe quel utilitaire d'utilisation du processeur que vous avez.
  • Le graphique semble un peu pire sur une machine différente: je vous fais confiance cette fois-ci.
  • Le pourcentage d'utilisation du processeur de base doit être continu. Par conséquent, si vous générez une onde aléatoire et mettez en surbrillance un élément qui ressemble au mot MAIL, il est évident que vous trichez.
  • Vous pouvez choisir la charge maximale à utiliser, mais celle-ci doit être suffisamment importante pour la voir clairement.
  • Vous devez suivre la linéarité de l'exemple. (Pour M, cela ressemble à ceci:% de base, puis augmentation soudaine jusqu'au maximum spécifié, baisse graduelle vers un% inférieur, remontant au maximum et baisse soudaine jusqu'au% de base.)
  • Si c'est illisible, les électeurs le remarqueront après tout.

Les failles standard s'appliquent. Postez les images aussi!

bebe
la source
9
Je ne vois plus de raison pour le vote serré. Personnellement, je trouve cela un défi amusant, bien qu’un peu spécifique au système.
seequ
6
Le problème que je vois avec le code golf est de juger si la lisibilité est suffisamment lisible. Si vous pouviez trouver un moyen de spécifier cela objectivement, cela améliorerait grandement le défi, mais c'est quand même une très bonne idée!
Martin Ender
3
c'est vraiment la même chose que votre image, mais je vous garantis que si vous ne le mettez pas en mots, les gens interpréteront "dessiner MAIL" très librement.
Martin Ender
33
+1, c'est tellement absurde que j'ai failli mourir de rire ... "c'est de la folie ..." "" de la folie ... CECI EST CODEGOLF !!! "
vaxquis
5
C'est une question géniale . J'aimerais être assez intelligent pour participer. Cela n'a pas d'importance, je suis intéressé par les solutions créatives d'autres personnes: P
Chris Cirefice le

Réponses:

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

Chaque caractère de la chaîne correspond à une seconde d'activité, du caractère ASCII 0(charge maximale) à ~(charge très légère). Le programme s'exécute sur une boucle synchronisée dans le temps, vous pouvez donc exécuter plusieurs instances pour obtenir de meilleurs résultats.

J'ai utilisé Python 2.7.6 sur OS X avec un processeur Intel Core i7, mais cela devrait fonctionner sur d'autres ordinateurs avec un peu d'ajustement (réglez la 0.001). La capture d'écran ci-dessous a été prise avec une activité de fond importante.

COURRIER

Mise à jour - J'ai été en mesure de produire un graphique plus clair avec time()/10une fréquence de mise à jour inférieure:

COURRIER

Et enfin, voici une version plus golfée ( 123 octets ) et son résultat :

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
grc
la source
250

Python, 358 281 268 221 194 octets

Monochrome est tellement l'année dernière. Cela utilise plusieurs processus et appels système pour obtenir des graphiques de processeur à deux couleurs !

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)

Sortie du moniteur d’activités (OS X 10.9):

Moniteur d'activité CPU Charge graph Graphique de l'historique du processeur du moniteur d'activité

Répétition sur le graphique de l'historique du processeur

Sortie de MenuMeters:

Sortie de MenuMeters

Toutes les sorties ont été générées avec une vitesse de mise à jour de 1s. Aucune tâche d’arrière-plan importante n’était en cours d’exécution, bien que cette sortie vainc assez facilement toute tâche de processeur à un seul thread.

Ce code suppose que vous avez 8 cœurs. Il devrait être assez facile de modifier pour moins / plus. Il est portable sur les systèmes Linux / UNIX (bien qu'il n'ait été testé que sur OS X) et devrait produire la même sortie bicolore pour tout moniteur de CPU capable de distinguer l'utilisateur du temps UC du système.

Cela fonctionne essentiellement en supprimant sept processus, chacun choisissant de passer une seconde en veille, en tournant dans le mode utilisateur ou en faisant tourner le noyau. Le spin en mode noyau est obtenu en demandant de grandes quantités de données /dev/urandom, ce qui oblige le back-up du pilote /dev/urandomà passer beaucoup de cycles de la CPU "système".

EDITED [07/21]: Réduit considérablement en utilisant à la fork()place de multiprocessing.Process( /dev/urandomne fonctionne de toute façon que sur les systèmes * NIX, cela ne réduit donc pas la portabilité). Notez cependant que le programme génère maintenant des tâches en arrière-plan ; vous devrez peut-être killall Python(ou similaire) pour vous débarrasser des mangeurs de CPU.


Je n'ai pas pu résister à la mise en place de quelques lettres supplémentaires. J'ai 16 lettres, plus quelques symboles:

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

L'alphabet complet est "ACDFHILMNOPTUVWY", avec les symboles "._ ~ / \". Il y a probablement beaucoup plus de personnages qui peuvent être représentés.

Code entièrement non-golfé pour les lettres supplémentaires:

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)
Nneonneo
la source
34
+1 pour donner aux lettres plus de définition en utilisant 2 couleurs
DustinDavis
4
Et +1 pour la création de lettre basée sur un tableau
GreenAsJade
1
Le A pourrait en fait être correctement rendu (avec un trou) avec 4 fils. Il faudrait cependant que certaines couleurs du moniteur du processeur coïncident.
Ruslan
@Ruslan: A quel moniteur de CPU pensez-vous? Mon moniteur n’affiche qu’un seul graphe agrégé, avec 0 <= système <= utilisateur <= 100 à chaque point (ce qui rend les "trous" impossibles à l’instant).
nneonneo
1
@nneonneo Je parle de moniteurs similaires au vôtre. Voir cette photo . Ici, si nous changeons le bleu en vert et le rouge et le violet en blanc, nous obtiendrons un joli "A" avec des trous.
Ruslan
133

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

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

Ce code est à peu près aussi portable que la Grande Pyramide de Kheops. Désolé pour ça. Les valeurs renvoyées mach_absolute_time()dépendent du matériel, mais sur ma machine, la valeur incrémente environ une fois par nanoseconde.

Voici le résultat:

Le mot "MAIL" indiqué dans le graphique de l'historique de mon processeur

Il y a deux graphiques car le processeur a deux cœurs. Je règle la charge maximale du processeur sur environ 90%, car le processus est susceptible de basculer entre les cœurs chaque fois que j'appelle usleep(). Avec une charge de 100%, le processus est enchaîné et les résultats sont illisibles ( voir ceci, par exemple )

ossifrage délirant
la source
1
Bon travail! Cela semble très intéressant. Pourriez-vous s'il vous plaît poster une petite explication du code? :)
duci9y
1
Je vois des accolades. pourquoi y a-t-il des accolades dans les boucles for? vous pouvez nous mettre en veille dans le second bloc du dernier bloc. Je pense que vous pouvez jouer au golf un peu plus facilement.
bebe
Ne pourriez-vous pas mettre la déclaration et l'initialisation des uint64_tvariables dans l'en-tête de la forboucle suivante ?
Joey
74
+1: "Ce code est à peu près aussi portable que la grande pyramide de Khéops"
Uwe Keim
@ Bien, non, les variables C doivent être déclarées au début d'un bloc. le mettre dans le bloc d'initialisation de pour lève une erreur. bien sûr, cela ne s'applique qu'à <C99
bebe
102

Ruby, 150 caractères

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}

Ce n’est pas si court jusqu’à présent, mais à mon avis, la sortie est plutôt sympa, alors j’ai pensé que je posterais ça de toute façon. Comme avec la plupart des autres solutions, vous devrez peut-être épingler le processus Ruby à un noyau en le préfixant avec taskset -c $core.

Le code est une simple combinaison de rotation / sommeil pendant un certain temps, ce qui devrait le rendre assez portable. Les dégradés lisses sont créés en faisant varier le rapport temps de rotation / sommeil.

MAIL écrit CPU Monitor

La diminution de la fréquence d'échantillonnage du processeur améliore l'aspect des bords:

Fréquence d'échantillonnage inférieure

En ajoutant quelques lettres supplémentaires à l’alphabet (qui AILMNUVWsont plus ou moins reconnaissables), nous pouvons aussi écrire quelques autres mots:

MAMAN, MAW, VILLAIN

Ces images ont été générées avec le code suivant:

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
}

Les mots pouvant être écrits avec les lettres implémentées peuvent être trouvés avec

grep -E '^[aijlmnuvw]+$' /usr/share/dict/words 
Ventero
la source
4
+1 pour l'extension en plus de mots!
Chris Cirefice
Vous auriez pu faire le mot "aluminium".
Oliver Daugherty-Long
@ OliverDaugherty-Long aluminium *
TuxCrafting, le
1
@ TùxCräftîñg Aluminium est une variante orthographique qui a une lettre supplémentaire et qui est le mot le plus long auquel je puisse penser qui marche.
Oliver Daugherty-Long le
48

Python, sur Intel Pentium 4 3.0Ghz, 180 166 145 141 138 octets

Appeler avec taskset -c 0 python cpu_graph_drawer.py.

taskset est nécessaire pour restreindre le processus à l’utilisation d’un seul processeur / cœur (hyperthreading dans mon cas).

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)

Le résultat n'est pas terrible. Celui-ci avec taskset -c 1

utilisateur80551
la source
9
J'adorerais voir cela avec un moniteur CPU qui ne lisse pas les courbes ...
Szabolcs
1
Moi aussi, mais je n'ai pas envie d'écrire un graphe d'utilisation conp cpu et gnome-system-monitorc'est la seule chose que je sache. Avez-vous des alternatives qui fonctionnent sur LMDE Cinnamon?
user80551
Activez l'option "Dessiner la CPU sous forme de graphique empilé" et définissez toutes les couleurs sur Noir.
Tejas Kale
@TejasKale Les lignes seraient toujours courbes.
user80551
Pour votre information: vous pouvez jouer au golf avec un groupe de personnages en utilisant a=[...]+[(.1,.2)]*10au lieu de .extend.
nneonneo
46

Java 8, 482 caractères

Chaque caractère de la chaîne signifie le nombre de threads à utiliser. Image prise sur Intel Core i3 (2 cœurs / 4 threads).

résultat

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

Edit : version plus golfée (322 caractères), même fonctionnalité:

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();
}}}
Tomáš Dvořák
la source
1
Il y a un signe moins que là qui a été interprété comme HTML et a gâché le formatage.
David Conrad
@ValekHalfHeart Les deux lignes suivantes devraient l'expliquer. Executor est un thread (gestionnaire de tâches asynchrone) exécutant des tâches (ici en boucle) jusqu'à l'interruption. Après l'avoir créé, le thread principal attend 1.5s, puis interrompt toutes les tâches.
PTwr
45
En ouvrant simplement Eclipse, mon graphique de processeur écrivait "Simple Mail Transfer Protocol".
lolesque
21

C, 78 octets

Vous n'avez jamais dit que nous ne pouvions pas accepter les entrées de l'utilisateur, sooo ..

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

Ce programme lit en standard et chaque fois qu’il lit un caractère, il exécute une perte de temps CPU gratuite, puis appelle de nouveau principal. Vous contrôlez la quantité de temps CPU utilisé en envoyant un spam à la touche Entrée à différentes vitesses.

Je l'ai couru sur un Intel i3 4130T, qui est un processeur raisonnablement nouveau. Toutefois, votre kilométrage peut varier. Si vous utilisez plus de temps processeur que vous ne pouvez le faire, essayez de jouer avec la quantité de décalage dans la boucle de délai.

Mon programme est génial car il:

  • est principalement cross-platform, cela devrait fonctionner avec très peu de violon sur n'importe quel * nix
  • défait la question
  • super jeu en fin de partie

Après quelques essais, j'ai créé un graphique ressemblant à ceci:Graphique de la CPU

Wug
la source
Il est utile de le limiter à un seul cœur de processeur avec taskset, a.la. taskset -c 1 [file]
Wug
2
Je ne vois rien dans les exigences relatives au problème qui indique que nos soumissions seront invoquées sous le nomyes | [program]
Wug le
1
"super jeu en fin de partie" m'a fait lol dur. +1
Christoph
1
Cette réponse est trop bonne cependant, les échappatoires soient maudites xD!
Urne Octopus Magique