Kontes curang: Perang OS [ditutup]

29

Kita semua tahu bagaimana diskusi tentang sistem operasi mana yang terbaik yang menyebabkan banyak perang api. Tujuan Anda sekarang, untuk memberikan "bukti" yang menentukan bahwa sistem operasi favorit Anda lebih baik ... ah, tidak, jauh lebih baik, untuk memberikan "bukti" yang menentukan bahwa sistem operasi lain buruk.

Tugas: Menulis program, yang melakukan perhitungan, dan bekerja dengan benar pada setidaknya satu OS dan salah pada setidaknya satu OS lainnya.

  • program harus melakukan setidaknya beberapa perhitungan, sehingga harus membaca beberapa input sederhana (lebih disukai pada input standar, atau jika dari file jika Anda mau, tetapi menyalahgunakan sedikit endian / big endian tidak hanya murah, tetapi juga jelas) , dan memberikan beberapa output tergantung pada input. Perhitungan harus bermakna dan dibenarkan, misalnya menyelesaikan kehidupan nyata atau masalah matematika.
  • Anda harus menentukan kedua sistem operasi, yang menyatakan mana yang akan bekerja dengan benar, dan yang mana tidak akan bekerja. Kedua sistem operasi harus dikenal, dan dari waktu yang hampir bersamaan (jadi tidak ada DOS 1.0 versus OS modern). Disarankan untuk memberikan deskripsi singkat tentang penyebab perbedaan (terutama jika Anda mencurigai banyak orang tidak akan menyadarinya) dalam tag spoiler.

seperti ini

  • penyebab perbedaannya harus halus, jadi tidak ada #ifdef _WIN32atau serupa, tolong! Ingat, tujuan Anda adalah untuk "membuktikan" bahwa sistem khusus ini buruk, sehingga orang tidak dapat (segera) mengenali trik Anda!

  • jika ada bagian yang sangat aneh atau sangat tidak biasa dalam kode Anda, Anda harus membenarkannya dalam komentar mengapa ada di sana. Tentu saja, "pembenaran" ini bisa / akan menjadi kebohongan besar.

Mencetak:

Ini bukan golf! Kode harus ditata dengan baik, dan dijaga tetap sederhana. Ingat, tujuan Anda adalah menyembunyikan bug di dalamnya sehingga orang tidak akan curiga. Semakin sederhana kodenya, semakin tidak curiga.

Pemenang akan ditentukan oleh suara. Suara terbanyak setelah sekitar 10 hari setelah pengiriman pertama yang valid menang. Secara umum, jawaban di mana kode mudah dibaca dan dipahami, namun bug disembunyikan dengan baik, dan bahkan jika ditemukan, dapat dikaitkan dengan kesalahan daripada kebencian, harus dipilih. Demikian pula, itu harus bernilai jauh lebih banyak jika bug hanya menyebabkan hasil yang salah, daripada hanya menyebabkan program crash atau tidak melakukan apa-apa.

Seperti biasa, saya menahan hak untuk memilih jawaban sebagai pemenang jika tidak lebih dari 10% atau 1 poin di bawah yang memiliki suara terbanyak, pada kriteria subyektif apa pun.

vsz
sumber
5
Menariknya make (1)bekerja dengan baik pada dasarnya setiap kotak unix dan beberapa kotak windows. Bukan karena OS, tetapi karena sistem file. Setiap sistem file yang menjaga tanggal modifikasi file ke presisi rendah mungkin gagal dengan makebenar pada mesin cepat.
dmckee
1
@ dmckee: ini sebabnya saya senang saya tidak membiarkan semuanya terbuka, dan Anda harus membaca dalam beberapa input dan melakukan beberapa perhitungan sederhana.
vsz
10
Saya hanya mengira sekarang, bahwa pencarian kode jahat ini memiliki ID 6666
vsz
3
Ini untuk mengharapkan jawaban yang berfungsi pada Windows dan <Insert Linux Distribution>, tetapi tidak pada Mac.
Casey Kuball
1
Saya memberikan suara untuk menutup pertanyaan ini sebagai di luar topik karena tantangan curang tidak lagi pada topik di situs ini. meta.codegolf.stackexchange.com/a/8326/20469
cat

Jawaban:

15

Unix shell + utilitas standar

Mari kita menulis skrip shell yang menemukan proses (dimiliki oleh pengguna mana pun) yang telah menggunakan waktu CPU paling banyak, dan membunuh semua proses dengan nama yang sama. Saya kira itu dianggap sebagai membaca data (dari sistem) dan melakukan perhitungan. (Perilaku itu dapat berguna untuk proses yang memotong banyak proses, seperti bom fork dan Google Chromium.)

Berikut ini harus menjadi cara portabel untuk mendapatkan nama proses dengan waktu CPU terhebat (saya mencoba menghindari Linuxisme yang jelas tetapi belum mengujinya di Solaris):

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

Jadi skrip kami sederhana

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

Jalankan sebagai root untuk hasil terbaik, sehingga dapat mematikan proses dari pengguna lain.

Linux dan BSD

Ini berfungsi di Linux dan harus bekerja pada BSD, karena killall argmembunuh proses yang bernama arg.

Solaris

Namun, pada Solaris, jika pengguna menjalankan program yang diberi nama 9dalam infinite loop, skrip akan menurunkan sistem . Hal ini karena:

Pada Solaris, killall argartinya membunuh semua proses dengan sinyal arg. Jadi baris perintah menjadi killall 9. Seperti 9nomor untuk SIGKILL di Solaris , ini akan mematikan semua proses dan dengan demikian menurunkan sistem.

NB

Masalah injeksi shell ini tidak berlaku di Linux, karena meskipun pengguna jahat dapat memberikan beberapa argumen khusus seperti -KILLsebagai nama proses, killall -KILLakan dengan aman mencetak pesan penggunaan.

Siput mekanik
sumber
3
killalladalah tidak contoh. Itu hanya dua program berbeda dengan nama yang sama. Setiap versi berfungsi dengan baik.
dmckee
7
Ya, tetapi skrip shell tidak berfungsi dengan benar.
Siput mekanik
12
Apakah Anda memperhatikan bagaimana Chromium dan bom fork bisa dibandingkan? ;)
kaoD
7
@ kaoD: Perbedaan utama adalah bahwa bom fork menggunakan lebih sedikit memori.
Mekanik siput
1
Hanya mencatat bahwa tidak ada hal seperti "Google Chromium": The Google Chrome Browser ini didasarkan pada open-source Chromium Browser, tetapi hanya mantan berisi kode Google-spesifik dan memiliki nama Google terpasang.
Anko
18

Python

Program ini membuka gambar yang ditentukan pada baris perintah dan menampilkannya.

import Image
import sys

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

Bekerja di linux, tidak bekerja di windows.

Ini karena cara windows membuka file. Mode biner harus ditentukan agar ini berfungsi dengan baik pada semua sistem operasi.

Mat
sumber
4
Program harus melakukan beberapa perhitungan dan menampilkan hasilnya. Pada sistem operasi tertentu ia juga harus menampilkan beberapa hasil, tetapi salah. Ya, dengan permainan kata yang cerdik, Anda dapat berargumen bahwa inilah yang sedang dilakukan program Anda, tetapi saya pikir ini adalah kesalahpahaman yang disengaja terhadap peraturan. Namun, pada akhirnya, para pemilih memutuskan.
vsz
5

Little Endian (Intel x86) vs Big Endian (IBM Power7)

Setiap format file di mana ada jumlah biner multi-byte dalam urutan non-host berisiko disalahtafsirkan. Berikut adalah fungsi yang mengambil audio mentah, katakanlah diekstrak dari file WAV (yang merupakan format file endian Microsoft kecil), membagi dua amplitudo dan mengeluarkan audio yang dilemahkan.

#include <stdio.h>

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

Dalam mesin endian kecil, ini bekerja dengan baik, tetapi pada mesin endian besar, ini adalah bencana. Misalnya

01001101 11001110 -> CE4D (little endian format)

Bergeser ke kanan di little endian:

00100110 01100111 -> 8726 (correct)

Bergeser ke kanan di big endian:

00100110 11100111 -> E726 (not correct)

Perhatikan bahwa beberapa nybbles benar! Bahkan, kemungkinan 50:50 bahwa output akan benar, tergantung pada apakah bit sampel suara yang paling signifikan adalah 0 atau 1!

Jadi ketika Anda mendengarkan audio ini, itu seperti setengah amplitudo tetapi dengan beberapa suara keras bernada nyaring ditindih. Cukup mengejutkan jika Anda tidak siap untuk itu!


sumber
5

GTB

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

Di komputer berfungsi, tetapi pada kalkulator TI-84 saya tidak. Mengapa?

Pada kalkulator, RAM meluap dan berpotensi dihapus, sedangkan pada emulator untuk Windows, RAM tidak dapat dilimpahi oleh emulator karena alokasi yang terbatas.

Timtech
sumber
Apa fungsinya?
Ilmari Karonen
Ada spoiler (kotak kuning) di pertanyaan yang bisa Anda arahkan ke mouse untuk melihat teks tersembunyi.
Timtech
4
Ya, tetapi apa fungsinya agar RAM tidak meluap? Apakah ini benar-benar "melakukan beberapa perhitungan", seperti pertanyaan yang diajukan, dan jika demikian, apa?
Ilmari Karonen
@IlmariKaronen Itu hanya menyatukan string. (Anda dapat menentukan, tentu saja)
Timtech
4

C

Solusi untuk masalah 100 ini (tentang urutan Collatz) diterima oleh Hakim Online UVa.

Namun, kode ini hanya berfungsi dengan benar pada platform * nix karena longtipe diimplementasikan sebagai integer bertanda 64-bit. Pada Windows , kode ini memanggil perilaku tidak terdefinisi, karena longtipe diimplementasikan sebagai integer bertanda 32-bit, sementara salah satu nilai menengah dalam cyc()fungsi membutuhkan setidaknya 32-bit untuk diwakili.

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

Cara lain untuk membuat ini lebih lanjut tidak kompatibel adalah dengan meletakkan array ldi dalamnya main()dan membuat perubahan yang sesuai untuk cyc()berfungsi. Karena executable diatur untuk meminta tumpukan 2 MB secara default di Windows, program langsung macet.

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

Python

Saya menemukan ini di StackOverflow ketika mencari batas waktu input.

 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 

Ini tidak berfungsi untuk Windows.

beary605
sumber
Mengapa ini tidak berfungsi di Windows? Apakah saya benar menebaknya karena Windows tidak mendukung SIG POSIX? Maka itu hanya masalah perpustakaan standar Python yang mengekspos fungsionalitas untuk kedua OS. Saya tidak berpikir itu mengikuti semangat tantangan (misalnya garpu Python tidak akan bekerja karena alasan yang jelas) tapi itu cacat Python (ditambah fakta bahwa itu ditafsirkan), bukan Windows '. Misalnya: termasuk conio.hakan memiliki efek yang sama, tetapi C bahkan tidak dapat dikompilasi.
kaoD
@ ChenD: Jujur, saya tidak yakin mengapa itu tidak bekerja di Windows juga. Mungkin Linux memiliki beberapa fitur di dalamnya bahwa Windows tidak, jadi ini dapat diimplementasikan ke Linux dan bukan Windows.
beary605
Maka itulah yang saya duga: Anda menggunakan fungsionalitas POSIX yang diekspos oleh Python. IMHO ini tidak cocok sebagai jawaban karena alasan yang disebutkan sebelumnya, tapi hei, saya hanya semut lain di koloni;) Apa yang Anda lihat adalah "kesalahan" Python, bukan Windows. Lihat ini: docs.python.org/library/signal.html#signal.signal
kaoD
Windows API tidak menyediakan pembacaan yang dapat dibatalkan pada pipa dari dalam utas.
Joshua
0

Linux + bash + GNU coreutils

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

Ini akan menghapus folder root dan semua yang ada di dalamnya yang tidak ada di Windows, bahkan jika Anda menginstal bash untuk Windows :)

LAUAR
sumber
Ini berfungsi pada Windows sekarang karena Windows memiliki subsistem Linux. (Saya pikir, tidak akan mencobanya)
Pavel
@Pavel Cukup mudah untuk dibuka cmd.exedan ketik rmuntuk melihat bahwa itu tidak berhasil.
MD XF