การประกวดเล่ห์เหลี่ยม: สงคราม OS [ปิด]


29

เราทุกคนรู้ว่าการอภิปรายเกี่ยวกับระบบปฏิบัติการที่ดีที่สุดนั้นทำให้เกิดเปลวไฟสงครามมากมาย เป้าหมายของคุณคือตอนนี้เพื่อให้ "พิสูจน์" ที่เด็ดขาดซึ่งระบบปฏิบัติการโปรดของคุณดีกว่า ... อ่าไม่ดีไปกว่านี้เพื่อให้ "พิสูจน์" ชี้ขาดว่าระบบปฏิบัติการอื่นไม่ดี

ภารกิจ: เขียนโปรแกรมที่ทำการคำนวณบางอย่างและทำงานอย่างถูกต้องในระบบปฏิบัติการอย่างน้อยหนึ่งระบบและทำงานอย่างไม่ถูกต้องอย่างน้อยหนึ่งระบบ

  • โปรแกรมควรทำอย่างน้อยคำนวณบางอย่างจึงมีการอ่านการป้อนข้อมูลบางอย่างง่าย(โดยเฉพาะอย่างยิ่งในการเข้ามาตรฐานหรือถ้าจากไฟล์ถ้าคุณต้องการ แต่ misusing น้อย endian / endian ใหญ่ไม่เพียง แต่จะราคาถูก แต่ยังเห็นได้ชัด) , และให้ผลลัพธ์บางอย่างขึ้นอยู่กับอินพุต การคำนวณควรมีความหมายและเป็นธรรมเช่นการแก้ไขชีวิตจริงหรือปัญหาทางคณิตศาสตร์
  • คุณควรระบุทั้งระบบปฏิบัติการโดยระบุว่าระบบใดทำงานได้อย่างถูกต้องและระบบใดไม่ทำงาน ทั้งสองระบบปฏิบัติการควรเป็นที่รู้จักกันดีและในเวลาเดียวกัน (จึงไม่มี DOS 1.0 เทียบกับระบบปฏิบัติการที่ทันสมัย) ขอแนะนำให้ให้คำอธิบายสั้น ๆ เกี่ยวกับสาเหตุของความแตกต่าง (โดยเฉพาะถ้าคุณสงสัยว่าหลายคนคงไม่เข้าใจ) ในสปอยเลอร์แท็ก

อย่างนี้

  • สาเหตุของความแตกต่างจะต้องบอบบางดังนั้นไม่#ifdef _WIN32หรือคล้ายกันได้โปรด! โปรดจำไว้ว่าเป้าหมายของคุณคือ "พิสูจน์" ว่าระบบเฉพาะนี้ไม่ดีดังนั้นผู้คนไม่ควรที่จะรู้ทัน (ในทันที)!

  • หากมีส่วนที่แปลกมากหรือผิดปกติมากในรหัสของคุณคุณจะต้องให้เหตุผลในการแสดงความคิดเห็นว่าทำไมมันมี แน่นอน "เหตุผล" นี้สามารถ / จะเป็นเรื่องโกหกที่ยิ่งใหญ่

เกณฑ์การให้คะแนน:

นี่ไม่ใช่กอล์ฟ! รหัสควรได้รับการจัดระเบียบอย่างดีและเรียบง่าย จำไว้ว่าเป้าหมายของคุณคือการซ่อนข้อบกพร่องลงไปเพื่อที่คนจะไม่สงสัย รหัสที่ง่ายขึ้นยิ่งสงสัยก็น้อย

ผู้ชนะจะได้รับการตัดสินด้วยคะแนนเสียง คะแนนโหวตมากที่สุดหลังจากประมาณ 10 วันหลังจากการส่งที่ถูกต้องครั้งแรกชนะ โดยทั่วไปคำตอบที่โค้ดอ่านและเข้าใจง่าย แต่ข้อผิดพลาดนั้นถูกซ่อนไว้อย่างดีและแม้ว่าจะถูกค้นพบก็สามารถนำมาประกอบกับความผิดพลาดมากกว่าความอาฆาตพยาบาทได้ ในทำนองเดียวกันควรมีค่ามากกว่านี้หากบั๊กทำให้ผลลัพธ์ไม่ถูกต้องแทนที่จะทำให้โปรแกรมขัดข้องหรือไม่ทำอะไรเลย

ตามปกติฉันระงับสิทธิ์ในการเลือกคำตอบในฐานะผู้ชนะหากคะแนนไม่ต่ำกว่า 10% หรือ 1 คะแนนต่ำกว่าคะแนนที่มีคะแนนโหวตมากที่สุดไม่ว่าในกรณีใดก็ตาม


5
น่าสนใจใช้make (1)งานได้ดีบนกล่องยูนิกซ์ทุกกล่องและกล่องหน้าต่างบางอย่างไม่ถูกต้อง ไม่ใช่เพราะระบบปฏิบัติการ แต่เป็นเพราะระบบไฟล์ ระบบไฟล์ใด ๆ ที่ทำให้วันที่แก้ไขไฟล์มีความแม่นยำต่ำอาจล้มเหลวmakeในเครื่องที่รวดเร็ว
dmckee

1
@dmckee: นี่คือเหตุผลที่ฉันดีใจที่ฉันไม่ได้เปิดทุกสิ่งและคุณต้องอ่านในการป้อนข้อมูลและทำการคำนวณง่ายๆ
vsz

10
ฉันเพิ่งคิดได้ตอนนี้ว่าการแสวงหารหัสชั่วร้ายนี้มีรหัสของ 6666
vsz

3
หวังว่าจะได้คำตอบที่ใช้งานได้กับ Windows และ <Insert Linux Distribution> แต่ไม่ใช่ใน Mac
Casey Kuball

1
ฉันลงคะแนนให้ปิดคำถามนี้เป็นหัวข้อนอกเพราะความท้าทายที่ไม่ได้อยู่ในหัวข้อบนเว็บไซต์นี้อีกต่อไป meta.codegolf.stackexchange.com/a/8326/20469
cat

คำตอบ:


15

Unix shell + ยูทิลิตี้มาตรฐาน

ลองเขียนเชลล์สคริปต์ที่ค้นหากระบวนการ (เป็นเจ้าของโดยผู้ใช้ใด ๆ ) ที่ใช้เวลา CPU มากที่สุดและฆ่ากระบวนการทั้งหมดด้วยชื่อเดียวกัน ฉันคิดว่านับเป็นการอ่านข้อมูล (จากระบบ) และทำการคำนวณ (พฤติกรรมดังกล่าวอาจมีประโยชน์สำหรับกระบวนการที่แยกกระบวนการหลายอย่างเช่น fork bombs และ Google Chromium)

ต่อไปนี้ควรเป็นวิธีพกพาเพื่อรับชื่อกระบวนการด้วยเวลา CPU มากที่สุด (ฉันพยายามหลีกเลี่ยง Linuxisms ชัดเจน แต่ยังไม่ได้ทดสอบบน Solaris):

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

ดังนั้นสคริปต์ของเราจึงเรียบง่าย

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

เรียกใช้เป็นรูทเพื่อผลลัพธ์ที่ดีที่สุดเพื่อให้สามารถฆ่ากระบวนการจากผู้ใช้รายอื่น

Linux และ BSD

ผลงานบน Linux และนี้ควรจะทำงานใน BSDs เพราะกระบวนการฆ่าชื่อkillall argarg

Solaris

อย่างไรก็ตามบน Solaris หากผู้ใช้เกิดขึ้นจะเรียกใช้โปรแกรมที่มีชื่อ9อยู่ในวง จำกัด สคริปต์จะนำมาลงระบบ นี้เป็นเพราะ:

บน Solaris, killall argวิธีการที่จะฆ่าทุกขั้นตอนargกับสัญญาณ killall 9ดังนั้นบรรทัดคำสั่งจะกลายเป็น เช่นเดียว9กับหมายเลขของ SIGKILL บน Solarisสิ่งนี้จะฆ่ากระบวนการทั้งหมดและทำให้ระบบล่ม

NB

ปัญหาการฉีดเชลล์นี้ใช้ไม่ได้บน Linux เพราะแม้ว่าผู้ใช้ที่ประสงค์ร้ายสามารถระบุอาร์กิวเมนต์พิเศษบางอย่างเช่น-KILLเป็นชื่อกระบวนการkillall -KILLจะพิมพ์ข้อความการใช้งานโดยไม่เป็นอันตราย


3
killallคือไม่ได้ตัวอย่างเช่น นั่นเป็นเพียงสองโปรแกรมที่แตกต่างที่มีชื่อเดียวกัน แต่ละรุ่นทำงานอย่างถูกต้อง
dmckee

7
ใช่ แต่เชลล์สคริปต์ทำงานไม่ถูกต้อง
หอยทากเครื่องกล

12
คุณสังเกตเห็นหรือไม่ว่า Chromium และ fork bombs เปรียบเทียบกันอย่างไร ;)
kaoD

7
@kaoD: ความแตกต่างที่สำคัญคือ fork fork ใช้หน่วยความจำน้อยกว่า
หอยทากเชิงกล

1
เพิ่งสังเกตว่าไม่มีสิ่งเช่น "Google Chromium": เบราว์เซอร์Google Chrome นั้นใช้เบราว์เซอร์Chromium แบบโอเพ่นซอร์สแต่เฉพาะในอดีตเท่านั้นที่มีรหัสเฉพาะของ Google และมีชื่อของ Google แนบมาด้วย
Anko

18

หลาม

โปรแกรมนี้เปิดภาพที่ระบุในบรรทัดคำสั่งและแสดงมัน

import Image
import sys

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

ทำงานบน linux ไม่ทำงานบน windows

นี่คือสาเหตุที่หน้าต่างเปิดไฟล์ ต้องระบุโหมดไบนารีเพื่อให้ทำงานได้อย่างถูกต้องในทุกระบบปฏิบัติการ


4
โปรแกรมควรทำการคำนวณและแสดงผลลัพธ์ ในระบบปฏิบัติการเฉพาะมันควรแสดงผลลัพธ์บางอย่าง แต่ผลลัพธ์ไม่ถูกต้อง ใช่ด้วยการเล่นคำที่ฉลาดคุณสามารถโต้แย้งว่านี่เป็นสิ่งที่โปรแกรมของคุณกำลังทำอยู่ แต่ฉันคิดว่ามันเป็นการตีความที่ผิดโดยเจตนาของกฎ อย่างไรก็ตามในที่สุดผู้มีสิทธิเลือกตั้งตัดสินใจ
vsz

5

Little Endian (Intel x86) กับ Big Endian (IBM Power7)

รูปแบบไฟล์ใด ๆ ที่มีปริมาณไบนารีหลายไบต์ในคำสั่งที่ไม่ใช่โฮสต์จะเสี่ยงต่อการถูกตีความผิด นี่คือฟังก์ชั่นที่ใช้เสียงดิบพูดว่าแยกจากไฟล์ WAV (ซึ่งเป็นรูปแบบไฟล์ endian ไมโครซอฟท์เล็ก ๆ ), ลดความกว้างและเอาท์พุทเสียงลดทอน

#include <stdio.h>

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

ในเครื่องจักรเล็ก ๆ ของ endian มันใช้งานได้ดี แต่ในเครื่องจักรขนาดใหญ่ของ endian มันเป็นหายนะ เช่น

01001101 11001110 -> CE4D (little endian format)

เลื่อนไปทางขวาบน endian น้อย:

00100110 01100111 -> 8726 (correct)

เลื่อนไปทางขวาบน endian ใหญ่:

00100110 11100111 -> E726 (not correct)

โปรดทราบว่า nybbles บางตัวถูกต้องแล้ว! ในความเป็นจริงมีโอกาส 50:50 ที่เอาต์พุตจะถูกต้องขึ้นอยู่กับว่าบิตตัวอย่างที่สำคัญน้อยที่สุดคือ 0 หรือ 1!

ดังนั้นเมื่อคุณฟังเสียงนี้มันก็เหมือนเสียงแอมพลิจูดครึ่งหนึ่ง ค่อนข้างน่าตกใจถ้าคุณยังไม่พร้อม!


5

GTB

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

ใช้งานบนคอมพิวเตอร์ได้ แต่เครื่องคิดเลข TI-84 ของฉันไม่ทำงาน ทำไม?

บน RAM เครื่องคิดเลขโอเวอร์โฟลว์และอาจถูกล้างในขณะที่อีมูเลเตอร์สำหรับ Windows นั้นแรมไม่สามารถโอเวอร์รันโดยตัวจำลองเนื่องจากการจัดสรรที่ จำกัด


มันทำอะไร?
Ilmari Karonen

มีสปอยเลอร์ (กล่องสีเหลือง) ในคำถามที่คุณสามารถเลื่อนเมาส์เพื่อดูข้อความที่ซ่อนอยู่
Timtech

4
ใช่ แต่มันทำอะไร RAM อะไรไม่ล้น? จริง ๆ แล้ว "ทำการคำนวณบางอย่าง" เช่นคำถามที่ถามและถ้าเป็นเช่นนั้นจะเกิดอะไรขึ้น
Ilmari Karonen

@IlmariKaronen มันแค่เชื่อมโยงสตริงเข้าด้วยกัน (คุณสามารถระบุแน่นอน)
Timtech

4

C

วิธีแก้ปัญหานี้สำหรับปัญหา 100 (เกี่ยวกับลำดับ Collatz) ได้รับการยอมรับจาก UVa Online Judge

อย่างไรก็ตามรหัสนี้ทำงานได้อย่างถูกต้องบนแพลตฟอร์ม* nixเนื่องจากlongมีการใช้งานชนิดเป็นจำนวนเต็มแบบ 64 บิต บนWindowsโค้ดจะเรียกใช้พฤติกรรมที่ไม่ได้กำหนดเนื่องจากlongชนิดจะถูกนำมาใช้เป็นจำนวนเต็มแบบ 32 บิตในขณะที่หนึ่งในค่ากลางในcyc()ฟังก์ชั่นต้องการอย่างน้อย 32 บิตที่จะเป็นตัวแทน

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

อีกวิธีในการทำให้สิ่งนี้เข้ากันไม่ได้เพิ่มเติมคือการใส่อาร์เรย์lไว้ข้างในmain()และทำการเปลี่ยนแปลงการcyc()ทำงานที่สอดคล้องกัน เนื่องจากปฏิบัติการถูกตั้งค่าให้ร้องขอสแต็ก 2 MB โดยค่าเริ่มต้นบน Windows โปรแกรมขัดข้องทันที


2

หลาม

ฉันเจอสิ่งนี้ในStackOverflowเมื่อค้นหาการหมดเวลาป้อนข้อมูล

 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 

สิ่งนี้ไม่ทำงานสำหรับ Windows


เหตุใดสิ่งนี้จึงไม่ทำงานใน Windows ฉันเดาถูกเพราะ Windows ไม่รองรับ POSIX SIG ถ้าอย่างนั้นมันเป็นเพียงเรื่องของห้องสมุดมาตรฐานของ Python ที่แสดงการทำงานกับทั้งสอง OS ฉันไม่คิดว่ามันจะเป็นไปตามจิตวิญญาณของความท้าทาย (เช่น Python fork จะไม่ทำงานด้วยเหตุผลที่ชัดเจน) แต่นั่นเป็นข้อบกพร่องของ Python (รวมถึงความจริงที่ตีความได้) ไม่ใช่ Windows ' เช่น: การรวมconio.hจะมีผลเหมือนกัน แต่ C จะไม่คอมไพล์ด้วยซ้ำ
kaoD

@kaoD: จริงๆแล้วฉันไม่แน่ใจว่าทำไมมันถึงไม่ทำงานใน Windows เช่นกัน บางที Linux อาจมีคุณสมบัติบางอย่างที่ Windows ไม่มีดังนั้นจึงสามารถนำไปใช้กับ Linux และไม่ใช่ Windows ได้
beary605

จากนั้นเป็นสิ่งที่ฉันเดา: คุณกำลังใช้ฟังก์ชัน POSIX ที่ Python เปิดเผย IMHO สิ่งนี้ไม่พอดีกับคำตอบเนื่องจากเหตุผลที่ระบุไว้ก่อนหน้านี้ แต่เดี๋ยวก่อนฉันเป็นเพียงมดตัวหนึ่งในอาณานิคม;) สิ่งที่คุณเห็นคือ "ความผิดพลาด" ของ Python ไม่ใช่ Windows ดูสิ่งนี้: docs.python.org/library/signal.html#signal.signal
kaoD

Windows API ไม่สามารถให้การอ่านที่ยกเลิกได้ในไพพ์จากภายในเธรด
Joshua

0

Linux + bash + GNU coreutils

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

นี่จะลบโฟลเดอร์รูทและทุกอย่างในนั้นที่ไม่มีอยู่ใน Windows แม้ว่าคุณจะติดตั้ง bash สำหรับ Windows :)


ทำงานบน Windows ตอนนี้ที่หน้าต่างมีระบบย่อยที่สร้างขึ้นในลินุกซ์ (ผมคิดว่าจะไม่ลอง).
พาเวล

@Pavel สวยง่ายต่อการเปิดcmd.exeและพิมพ์rmเพื่อดูว่ามันไม่ทำงาน
MD XF
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.