विकिरण-कठोर इरिडिएटर लिखिए


17

कार्य विकिरण-विकिरणित विकिरण लिखने का है। मेरा क्या मतलब है, बिल्कुल?

एक इर्रिडिएटर एक प्रोग्राम है जिसे इनपुट के रूप में एक स्ट्रिंग दिए जाने पर, स्ट्रिंग के सभी संभावित संस्करणों को हटाए गए एक वर्ण के साथ आउटपुट किया जाएगा। उदाहरण के लिए, इनपुट को देखते हुए Hello, world!, प्रोग्राम को आउटपुट देना चाहिए:

ello, world!
Hllo, world!
Helo, world!
Helo, world!
Hell, world!
Hello world!
Hello,world!
Hello, orld!
Hello, wrld!
Hello, wold!
Hello, word!
Hello, worl!
Hello, world

हालाँकि, एक विकिरणक को इसके विकिरण से बचाना चाहिए, इसलिए आपके द्वारा लिखा गया विकिरण भी जीवित रहना चाहिए जब इसे स्वयं के माध्यम से रखा जाए। यही है, जब आपके प्रोग्राम का कोई भी बाइट हटा दिया जाता है, तो प्रोग्राम को ठीक से काम करना चाहिए।

परीक्षण के मामलों

abc -> bc; ac; ab
foo bar -> oo bar:fo bar:fo bar:foobar:foo ar:foo br:foo ba
source -> ource;surce;sorce;souce;soure;sourc;

विशेष विवरण

  • आप हमारे मानक I / O नियमों द्वारा किसी भी स्वीकार्य विधि द्वारा इनपुट ले सकते हैं
  • आउटपुट या तो स्ट्रिंग्स की सूची हो सकती है या किसी वर्ण या वर्णों के समूह द्वारा मुद्रित सूची हो सकती है। अनुगामी परिसीमन स्वीकार्य है
  • आउटपुट किसी भी क्रम में हो सकता है जब तक कि इसमें सभी संभावित संस्करण शामिल हों
  • डुप्लिकेट प्रविष्टियों (जैसे Helo, world!पहले उदाहरण में दो s) को फ़िल्टर किया जा सकता है, लेकिन यह आवश्यक नहीं है
  • जैसा कि यह , बाइट्स में सबसे छोटा कार्यक्रम, जीत है

... या अल्पविराम शायद?
जोनाथन एलन

4
यह वास्तव में गोल्फ भाषाओं का पक्षधर है, क्योंकि हटाए गए C कार्यक्रम vमें voidसंकलन नहीं होगा
Krzysztof Szewczyk

3
@Krzysztof tbh मुझे लगता है कि अगर व्यावहारिकता और वाक्यविन्यास के कारण सभी व्यावहारिक भाषाएं विकिरण से बच नहीं पाएंगी। न केवल यह चुनौती, बल्कि सभी आरएच चुनौतियां।
शायरु असाकोतो

जवाबों:


13

05AB1E , 29 26 बाइट्स

æIg<ùˆ\æIg<ùˆ\æIg<ùˆ¯¯{Å`s

इसे ऑनलाइन आज़माएं! , या सभी विकिरणित संस्करणों का प्रयास करें

सबसे छोटा विकिरण जो मुझे मिल सकता है वह है 5 बाइट्स:

æ        # powerset of the input
 Ig      # length of the input
   <     # - 1
    ù    # elements of a with length b

यह विचार कि 3 बार दोहराना है, फिर बहुसंख्यक मतदान करें:

æIg<ù         # irradiate
     ˆ        # add the result to the global array
      \       # pop (in case the above instruction gets irradiated)
æIg<ùˆ\       # idem
æIg<ùˆ        # no pop, it's okay to dirty the stack at this point
¯             # push global array
 ¯            # and again, so at least one goes through
  {           # sort
   Å          # conveniently ignored by the parser
    `         # dump
     s        # swap
              # and implicitly output

Å2-बाइट आदेशों के लिए एक उपसर्ग है, लेकिन कोई Å`आदेश नहीं है , जिसके कारण इसे Åअनदेखा किया जाता है। हमें बाद में इसकी आवश्यकता होगी।

छांटना सुनिश्चित करता है कि बहुमत वोट सरणी के बीच में है। डंपिंग तब स्वैपिंग स्टैक के शीर्ष पर उस मान को प्राप्त करता है।

शुरुआती हिस्से में किसी भी तरह की गड़बड़ी से वैश्विक सरणी में त्रुटि होती है, जो बहुसंख्यक वोट से हल हो जाती है। अंतिम {Å`sबिट में विकिरण कारण के बारे में बहुत पेचीदा हैं:

  • Å वैसे भी नजरअंदाज किया जाता है, इसलिए इसे ठीक करना ठीक है

  • यदि बैकटिक विकिरणित है, Å`sबन जाता है Ås, जो कि "एरे के मध्य मिलता है" विस्तारित कमांड है।

  • यदि {या sविकिरणित हैं, तो इसका मतलब है कि और कुछ नहीं है, इसलिए वैश्विक सरणी तीन बार समान मूल्य है। उस स्थिति में हमें छँटाई / अदला-बदली की ज़रूरत नहीं है, कोई भी मूल्य काम करेगा।


3
बहुत प्रभावशाली! मुझे नहीं लगता था कि मैं आरएच चुनौती पर 05AB1E उत्तर देखूंगा। मैं इस उत्तर को पुरस्कृत करने के लिए एक इनाम जोड़ूंगा (और चुनौती को थोड़ा और विस्तार दूंगा और साथ ही मुझे लगता है) अभी। आपने मेरे बहुत सारे जवाबों को हासिल किया है, इसलिए आप उन लोगों के लिए भी क्रेडिट के पात्र हैं! :)
केविन क्रूज़सेन

3
वास्तव में, मैंने आरएच चुनौती पर 05AB1E उत्तर पहले देखा है । फिर भी, बहुत प्रभावशाली!
केविन क्रूज़सेन

5

8086 मशीन कोड (MS-DOS .COM), 83 बाइट्स

DOSBox या अपने पसंदीदा भाप संचालित कंप्यूटिंग इंजन में चलने योग्य। इर्रिरेज करने के लिए स्ट्रिंग को कमांड लाइन तर्क के रूप में दिया गया है।

बाइनरी:

00000000 : EB 28 28 8A 0E 80 00 49 BD 83 00 B4 02 51 8A 0E : .((....I.....Q..
00000010 : 80 00 BE 82 00 AC 39 EE 74 04 88 C2 CD 21 E2 F5 : ......9.t....!..
00000020 : 59 45 B2 0A CD 21 E2 E5 C3 90 EB D7 D7 8A 0E 80 : YE...!..........
00000030 : 00 49 BD 83 00 B4 02 51 8A 0E 80 00 BE 82 00 AC : .I.....Q........
00000040 : 39 EE 74 04 88 C2 CD 21 E2 F5 59 45 B2 0A CD 21 : 9.t....!..YE...!
00000050 : E2 E5 C3                                        : ...

पठनीय:

cpu 8086
org 0x100
    jmp part2
    db 0x28

part1:
    mov cl, [0x80]
    dec cx
    mov bp, 0x83
    mov ah, 0x02

.l:
    push cx
    mov cl, [0x80]
    mov si, 0x82
.k:
    lodsb
    cmp si, bp
    je .skip
    mov dl, al
    int 0x21
.skip:
    loop .k
    pop cx
    inc bp
    mov dl, 10
    int 0x21
    loop .l
    ret

    nop
part2:
    jmp part1
    db 0xd7
    mov cl, [0x80]
    dec cx
    mov bp, 0x83
    mov ah, 0x02

.l:
    push cx
    mov cl, [0x80]
    mov si, 0x82
.k:
    lodsb
    cmp si, bp
    je .skip
    mov dl, al
    int 0x21
.skip:
    loop .k
    pop cx
    inc bp
    mov dl, 10
    int 0x21
    loop .l
    ret

मंद होना

सक्रिय भाग को डुप्लिकेट किया जाता है ताकि विकिरण से हमेशा एक अछूता रहे। हम जंप के माध्यम से स्वस्थ संस्करण का चयन करते हैं। प्रत्येक कूद एक छोटी छलांग है, और इसलिए केवल दो बाइट्स लंबा है, जहां दूसरा बाइट विस्थापन है (यानी कूदने की दूरी, संकेत निर्धारण दिशा के साथ)।

हम कोड को चार भागों में विभाजित कर सकते हैं जिन्हें विकिरणित किया जा सकता है: कूद 1, कोड 1, कूद 2 और कोड 2। विचार यह है कि यह सुनिश्चित करने के लिए कि एक साफ कोड भाग हमेशा उपयोग किया जाता है। यदि कोड भागों में से एक को विकिरणित किया जाता है, तो दूसरे को चुना जाना चाहिए, लेकिन अगर एक जंप का विकिरण किया जाता है, तो दोनों कोड भाग साफ होंगे, इसलिए यह कोई फर्क नहीं पड़ेगा कि कौन सा चुना गया है।

दो जंप भागों के होने का कारण इसके पहले भाग में विकिरण का पता लगाना है। यदि पहला कोड भाग विकिरणित है, तो इसका मतलब है कि हम निशान से एक बाइट तक पहुंच जाएंगे। यदि हम यह सुनिश्चित करते हैं कि इस तरह का एक बॉटेड लैंडिंग कोड 2 का चयन करता है, और एक उचित लैंडिंग कोड 1 का चयन करता है, तो हम सुनहरे हैं।

दोनों छलांगों के लिए, हम विस्थापन बाइट की नकल करते हैं, प्रत्येक कूद भाग 3 बाइट्स लंबा बनाते हैं। यह सुनिश्चित करता है कि दो अंतिम बाइट्स में से एक में विकिरण अभी भी कूद को वैध बना देगा। पहली बाइट में विकिरण, कूद को बिल्कुल भी होने से रोक देगा, क्योंकि अंतिम दो बाइट्स पूरी तरह से अलग निर्देश बनाएंगे।

पहली छलांग लें:

EB 28 28        jmp +0x28 / db 0x28

यदि किसी भी 0x28बाइट को हटा दिया जाता है, तो यह अभी भी उसी स्थान पर कूद जाएगा। यदि 0xEBबाइट हटा दी जाती है, तो हम इसके साथ समाप्त हो जाएंगे

28 28           sub [bx + si], ch

जो MS-DOS पर एक सौम्य निर्देश है (अन्य जायके असहमत हो सकते हैं), और फिर हम कोड 1 के माध्यम से गिर जाते हैं, जो कि साफ होना चाहिए, क्योंकि क्षति कूद 1 में थी।

यदि कूद लिया जाता है, तो हम दूसरी छलांग पर उतरते हैं:

EB D7 D7        jmp -0x29 / db 0xd7

यदि यह बाइट अनुक्रम बरकरार है, और हम निशान पर सही उतरते हैं, तो इसका मतलब है कि कोड 1 साफ था, और यह निर्देश उस हिस्से पर वापस कूदता है। डुप्लिकेट किए गए विस्थापन बाइट इसकी गारंटी देता है, भले ही यह इन विस्थापन बाइट्स में से एक है जो क्षतिग्रस्त हो गए थे। यदि हम या तो एक बाइट को बंद कर देते हैं (एक क्षतिग्रस्त कोड 1 या कूद 1 के कारण) या 0xEBबाइट क्षतिग्रस्त है, तो दो शेष बाइट भी सौम्य होंगे:

D7 D7           xlatb / xlatb

जो भी मामला है, अगर हम उन दो निर्देशों को निष्पादित करते हैं, तो हम जानते हैं कि या तो कूद 1, कोड 1, या कूद 2 को विकिरणित किया गया था, जो एक गिरावट के माध्यम से कोड 2 को सुरक्षित बनाता है।

परिक्षण

.COM फ़ाइल के सभी संस्करणों को स्वचालित रूप से बनाने के लिए निम्न प्रोग्राम का उपयोग किया गया था। यह एक BAT फ़ाइल भी बनाता है जिसे लक्ष्य वातावरण में चलाया जा सकता है, जो प्रत्येक विकिरणित बाइनरी को चलाता है, और पाठ फ़ाइलों को अलग करने के लिए अपने आउटपुट को पाइप करता है। मान्य करने के लिए आउटपुट फ़ाइलों की तुलना करना काफी आसान है, लेकिन DOSBox के पास नहीं है fc, इसलिए इसे BAT फ़ाइल में नहीं जोड़ा गया।

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    FILE *fin, *fout, *fbat;
    int fsize;
    char *data;

    if (!(fin = fopen(argv[1], "rb")))
    {
        fprintf(stderr, "Could not open input file \"%s\".\n", argv[1]);
        exit(1);
    }

    if (!(fbat = fopen("tester.bat", "w")))
    {
        fprintf(stderr, "Could not create BAT test file.\n");
        exit(2);
    }

    fseek(fin, 0L, SEEK_END);
    fsize = ftell(fin);
    fseek(fin, 0L, SEEK_SET);

    if (!(data = malloc(fsize)))
    {
        fprintf(stderr, "Could not allocate memory.\n");
        exit(3);
    }

    fread(data, 1, fsize, fin);

    fprintf(fbat, "@echo off\n");

    for (int i = 0; i < fsize; i++)
    {
        char fname[512];

        sprintf(fname, "%03d.com", i);
        fprintf(fbat, "%s Hello, world! > %03d.txt\n", fname, i);

        fout = fopen(fname, "wb");

        fwrite(data, 1, i, fout);
        fwrite(data + i + 1, 1, fsize - i - 1, fout);

        fclose(fout);
    }

    free(data);
    fclose(fin);
    fclose(fbat);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.