Concurso discreto: la guerra del sistema operativo [cerrado]

29

Todos sabemos cómo la discusión sobre cuál es el mejor sistema operativo causó muchas guerras de llamas. Su objetivo ahora es proporcionar una "prueba" decisiva de que su sistema operativo favorito es mejor ... ah, no, mucho mejor, proporcionar una "prueba" decisiva de que otro sistema operativo es malo.

La tarea: escribir un programa, que haga algunos cálculos, y funcione correctamente en al menos un sistema operativo e incorrectamente en al menos otro.

  • el programa debe hacer al menos algunos cálculos, por lo que tiene que leer alguna entrada simple (preferiblemente en la entrada estándar, o si es de archivos si lo desea, pero el mal uso de little endian / big endian no solo sería barato, sino también obvio) , y proporcionar algo de salida dependiendo de la entrada. Los cálculos deben ser significativos y justificados, por ejemplo, resolver una vida real o un problema matemático.
  • debe especificar ambos sistemas operativos, indicando en cuál funcionará correctamente y en cuál no. Ambos sistemas operativos deben ser bien conocidos, y aproximadamente desde el mismo tiempo (por lo que no hay DOS 1.0 versus un SO moderno). Se recomienda proporcionar una breve descripción sobre la causa de la diferencia (especialmente si sospecha que muchas personas no se darían cuenta) en las etiquetas de spoiler.

Me gusta esto

  • La causa de la diferencia tiene que ser sutil, así que no #ifdef _WIN32o similar, ¡por favor! Recuerde, su objetivo es "probar" que este sistema específico es malo, por lo que las personas no deberían ser capaces (inmediatamente) de detectar su truco.

  • Si hay una parte muy extraña o muy inusual en su código, debe justificarlo en los comentarios por qué está allí. Por supuesto, esta "justificación" puede / será una gran mentira.

Tanteo:

¡Esto no es un golf! El código debe estar bien organizado y ser simple. Recuerde, su objetivo es ocultar un error para que la gente no sospeche de ello. Cuanto más simple es el código, menos sospechoso es.

El ganador se decidirá por votos. La mayoría de los votos después de aproximadamente 10 días después de la primera presentación válida gana. En general, las respuestas donde el código es fácil de leer y comprender, pero el error está bien oculto, e incluso si se descubre, se puede atribuir a un error en lugar de a la malicia, se debe votar. Del mismo modo, debería valer mucho más si el error solo causa un resultado incorrecto, en lugar de causar que el programa se bloquee o no haga nada.

Como de costumbre, me retengo el derecho de elegir una respuesta como ganador si no está más del 10% o 1 punto por debajo de la que tiene más votos, en cualquier criterio subjetivo.

vsz
fuente
55
Curiosamente make (1)funciona correctamente en prácticamente todos los cuadros de Unix y de forma incorrecta en algunos cuadros de Windows. No por los sistemas operativos, sino por los sistemas de archivos. Cualquier sistema de archivos que mantenga las fechas de modificación de archivos con baja precisión puede fallar makecorrectamente en una máquina rápida.
dmckee
1
@dmckee: es por eso que me alegro de no haber dejado todo abierto, y tienes que leer algunas entradas y hacer algunos cálculos simples.
vsz
10
Solo me imaginé ahora, que esta búsqueda del código malvado tiene el Id de 6666
vsz
3
Esperemos una respuesta que funcione en Windows y <Insert Linux Distribution>, pero no en Mac.
Casey Kuball
1
Estoy votando para cerrar esta pregunta como fuera de tema porque los desafíos poco claros ya no están en el tema en este sitio. meta.codegolf.stackexchange.com/a/8326/20469
gato

Respuestas:

15

Unix shell + utilidades estándar

Escribamos un script de shell que encuentre el proceso (propiedad de cualquier usuario) que haya utilizado más tiempo de CPU y elimine todos los procesos con el mismo nombre. Supongo que eso cuenta como leer datos (del sistema) y realizar un cálculo. (Ese comportamiento podría ser útil para procesos que desequilibran muchos procesos, como las bombas de horquilla y Google Chromium).

La siguiente debería ser una forma portátil de obtener el nombre del proceso con el mayor tiempo de CPU (intenté evitar Linuxismos obvios pero no lo he probado en Solaris):

ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2

Entonces nuestro guión es simplemente

killall `ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2`

Ejecútelo como root para obtener mejores resultados, de modo que pueda eliminar procesos de otros usuarios.

Linux y BSD

Esto funciona en Linux y debería funcionar en los BSD, porque killall argmata los procesos nombrados arg.

Solaris

Sin embargo, en Solaris, si un usuario ejecuta un programa denominado 9en un bucle infinito, el script desactivará el sistema . Esto es porque:

En Solaris, killall argsignifica matar todos los procesos con la señal arg. Entonces la línea de comando se convierte killall 9. Como 9es el número de SIGKILL en Solaris , esto matará todos los procesos y, por lo tanto, derribará el sistema.

nótese bien

Este problema de inyección de shell no se aplica en Linux, porque aunque el usuario malintencionado podría proporcionar algún argumento especial, como el -KILLnombre de un proceso, killall -KILLimprimirá un mensaje de uso de forma inofensiva.

Caracol mecánico
fuente
3
killallNo es un ejemplo. Que solo dos programas diferentes con el mismo nombre. Cada versión funciona correctamente.
dmckee
77
Sí, pero el script de shell no funciona correctamente.
Caracol mecánico
12
¿Te diste cuenta de cómo el cromo y las bombas de horquilla son comparables? ;)
kaoD
77
@kaoD: La diferencia clave es que las bombas de horquilla usan menos memoria.
Caracol mecánico
1
Solo señalando que no existe tal cosa como "Google Chromium": el navegador Google Chrome se basa en el navegador de código abierto Chromium , pero solo el primero contiene un código específico de Google y tiene el nombre de Google adjunto.
Anko
18

Pitón

Este programa abre la imagen especificada en la línea de comando y la muestra.

import Image
import sys

with open(sys.argv[1]) as f:
    im = Image.open(f)
    im.show()

Funciona en Linux, no funciona en Windows.

Esto se debe a la forma en que Windows abre los archivos. Se debe especificar el modo binario para que funcione correctamente en todos los sistemas operativos.

Mate
fuente
44
El programa debe hacer algunos cálculos y mostrar los resultados. En un sistema operativo específico, también debería mostrar algunos resultados, pero incorrectos. Sí, con un juego de palabras inteligente podría argumentar que esto es exactamente lo que está haciendo su programa, pero creo que es una mala interpretación deliberada de las reglas. Sin embargo, en última instancia, los votantes deciden.
vsz
5

Little Endian (Intel x86) frente a Big Endian (IBM Power7)

Cualquier formato de archivo donde haya cantidades binarias de varios bytes en un orden que no sea de host corre el riesgo de ser malinterpretado. Aquí hay una función que toma audio sin formato, por ejemplo, extraído de un archivo WAV (que es un formato de archivo pequeño endian de Microsoft), reduce a la mitad la amplitud y genera el audio atenuado.

#include <stdio.h>

int main()
{
    short audio;
    while (fread(&audio, sizeof(short), 1, stdin))
    {
        audio >>= 1;
        fwrite(&audio, sizeof(short), 1, stdout);
    }
    return 0;
}

En máquinas endian pequeñas, esto funciona muy bien, pero en máquinas endian grandes, es un desastre. P.ej

01001101 11001110 -> CE4D (little endian format)

Desplazar a la derecha en little endian:

00100110 01100111 -> 8726 (correct)

Desplazar a la derecha en Big Endian:

00100110 11100111 -> E726 (not correct)

¡Tenga en cuenta que algunas de las nybbles son correctas! De hecho, es una posibilidad 50:50 de que la salida sea correcta, ¡dependiendo de si el bit menos significativo de la muestra de sonido es 0 o 1!

Entonces, cuando escuchas este audio, es como la mitad de la amplitud, pero con un poco de ruido agudo y agudo superpuesto. ¡Bastante sorprendente si no estás preparado para ello!


fuente
5

GTB

:"-→_[_+_→_]

En la computadora funciona, pero en mi calculadora TI-84 no. ¿Por qué?

En la calculadora, la RAM se desborda y se borra potencialmente, mientras que en el emulador para Windows, el emulador no puede desbordar la RAM debido a la asignación limitada.

Timtech
fuente
¿Qué hace?
Ilmari Karonen
Hay un spoiler (recuadro amarillo) en la pregunta sobre el que puede pasar el mouse para ver el texto oculto.
Timtech
44
Sí, pero ¿qué hace que la RAM no se desborde? ¿Realmente "hace algunos cálculos", como la pregunta, y si es así, qué?
Ilmari Karonen
@IlmariKaronen Simplemente concatena las cadenas. (Puede especificar, por supuesto)
Timtech
4

do

Esta solución al problema 100 (sobre la secuencia de Collatz) es aceptada por el juez en línea de UVa.

Sin embargo, este código solo funciona correctamente en la plataforma * nix ya que el longtipo se implementa como un entero con signo de 64 bits. En Windows , el código invoca un comportamiento indefinido, ya que el longtipo se implementa como un entero con signo de 32 bits, mientras que uno de los valores intermedios en la cyc()función necesita al menos 32 bits para representarlo.

#include <stdio.h>

#define swap(a, b, t) t __tmp__ = a; a = b; b = __tmp__;
#define M 1000000

short l[M] = {0, 1};

int cyc(long n) { // HERE
    if (n < M && l[n]) return l[n];
    n = n & 0x1 ? 3 * n + 1 : n >> 1;
    return n < M ? (l[n] = cyc(n)) + 1 : cyc(n) + 1;
}

int max(int a, int b) { return a > b ? a : b; }

int main() {
    #ifndef ONLINE_JUDGE
    // freopen("input.txt", "r", stdin);
    #endif
    int i, j, m;
    while (scanf("%d %d", &i, &j) == 2) {
          printf("%d %d ", i, j);
          if (i > j) { swap(i, j, int); }
          for (m = 0; i <= j; i++)
              m = max(m, cyc(i));
          printf("%d\n", m);
    }

    return 0;
}

Otra forma de hacer que esto sea aún más incompatible es colocar la matriz ldentro main()y hacer los cambios correspondientes para cyc()funcionar. Como el ejecutable está configurado para solicitar una pila de 2 MB de forma predeterminada en Windows, el programa se bloquea de inmediato.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
2

Pitón

Encontré esto en StackOverflow cuando buscaba tiempos de espera de entrada.

 import signal 
 TIMEOUT = 5

 def interrupted(signum, frame): 
     print 'interrupted!' 
 signal.signal(signal.SIGALRM, interrupted) 

 def input(): 
     try: 
         print 'You have 5 seconds to type in your stuff...' 
         foo = raw_input() 
         return foo 
     except: 
         return

 signal.alarm(TIMEOUT) 
 s = input()
 signal.alarm(0) 
 print 'You typed', s 

Esto no funciona para Windows.

beary605
fuente
¿Por qué esto no funciona en Windows? ¿Estoy adivinando que es porque Windows no admite POSIX SIG? Entonces es solo cuestión de que las bibliotecas estándar de Python expongan la funcionalidad a ambos sistemas operativos. No creo que siga el espíritu del desafío (por ejemplo, la bifurcación de Python tampoco funcionará por razones obvias), pero esa es la falla de Python (más el hecho de que está interpretada), no la de Windows. Por ejemplo: incluir conio.htendría el mismo efecto, pero C ni siquiera compilará.
kaoD
@kaoD: Sinceramente, tampoco estoy seguro de por qué no funciona en Windows. Tal vez Linux tiene algunas características que Windows no tiene, por lo que esto se puede implementar en Linux y no en Windows.
beary605
Entonces es lo que supuse: estás usando la funcionalidad POSIX expuesta por Python. En mi humilde opinión, esto no encaja como una respuesta debido a la razón indicada anteriormente, pero bueno, yo soy solo otra hormiga en la colonia;) Lo que ves es la "falla" de Python, no Windows. Vea esto: docs.python.org/library/signal.html#signal.signal
kaoD
La API de Windows no proporciona lectura cancelable en una tubería desde el hilo.
Joshua
0

Linux + bash + GNU coreutils

rm --no-preserve-root -R -dir /

Esto borrará la carpeta raíz y todo lo que no existe en Windows, incluso si instala bash para Windows :)

LAUAR
fuente
Esto funciona en Windows ahora que Windows tiene un subsistema Linux incorporado. (Creo que no lo probaré)
Pavel
@Pavel Bastante simple de abrir cmd.exey escribir rmpara ver que no funciona.
MD XF