เขียนโปรแกรมที่เปลี่ยนทุก ๆ 17 บิตของไฟล์ข้อความเป็น 1


10

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

"มันเหมือนทุกครั้งที่คุณเรียกใช้โปรแกรมนี้คุณยอมรับข้อกำหนดในการให้บริการที่ระบุว่าบิตที่ 17 บนฮาร์ดไดรฟ์ของคุณจะกลายเป็น 1"

เป้าหมาย: เขียนโปรแกรมที่จะทำสำเนาไฟล์อย่างถูกต้องและแปลงไฟล์ข้อความทุก ๆ 17 บิตให้เป็น 1

  • คุณไม่สามารถเปลี่ยนไฟล์ทุกๆบิตเป็น 1 เช่นโปรแกรมของคุณจะต้องแสดงความฉลาดว่ามันมีการกำหนดเป้าหมายเพียงทุก ๆ 17 บิต
  • คุณไม่สามารถเขียนไฟล์ต้นฉบับในรูปแบบหรือรูปแบบใด ๆ
  • ผู้ชนะเลิศคือการส่งโปรแกรมมีขนาดเล็กที่สุดในตอนท้ายของเดือน

ขอให้สนุกกับสิ่งนี้! ไป!


7
1. คำถามทุกข้อต้องการเกณฑ์การชนะอย่างมีวัตถุประสงค์ คำถามส่วนใหญ่code-golfคือรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ code-challengeต้องการระบบการให้คะแนนที่กำหนดไว้อย่างดี 2. การเปลี่ยนฮาร์ดไดรฟ์ทุก ๆ 18 บิตให้เป็น 1 จะทำได้โดยการเขียนลงไปที่ไดรฟ์โดยตรง ไม่สามารถทำได้โดยการสร้างและ / หรือแก้ไขไฟล์ 3. การทำเช่นนี้จะทำให้ไดรฟ์ทั้งหมดใช้ไม่ได้ดังนั้นโซลูชันที่เข้ากันได้จะถูกทำลาย ผมไม่ทราบว่าวิธีการที่ดีในชุมชนจะได้รับการร้องขอไปยังมัลแวร์เขียน ...
เดนนิส

2
ฉันลงคะแนนให้เปิดคำถามนี้อีกครั้งถ้ามีแค่ตัวแทนมากพอ :/
Sammitch

3
@ สตีฟเวอร์ริลล์ฉันจะเปลี่ยนเป็นโค้ดกอล์ฟ แต่ฉันจะเปลี่ยนจากบิตที่ 18 เป็นบิตที่ 17 เพื่อให้สิ่งที่น่าสนใจ
C. Tewalt

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

1
ไฟล์จะอ่านได้อย่างไร? stdin?
มิโล

คำตอบ:


9

CJam, 22 ไบต์

q256b2H#b1f|2H#b256b:c

ลองออนไลน์

สัมผัสทุก ๆ วันที่ 17 นับจากครั้งสุดท้าย

ฉันใช้ STDIN และ STDOUT เนื่องจาก CJam ไม่มีไฟล์ I / O หากไม่ได้รับอนุญาตโปรแกรมสามารถห่อในสคริปต์ Bash ที่ราคา 24 ไบต์พิเศษ:

cjam <(echo q256b2H#b1f\|2H#b256b:c)<"$1">"$2"

มันทำงานอย่างไร

q                      " Read from STDIN.                                                 ";
 256b                  " Convert to integer by considering the input a base 256 number.   ";
     2H#b              " Convert to array by considering the integer a base 2**17 number. ";
         1f|           " Set the LSB of every integer in the array element to 1.          ";
            2H#b       " Convert to integer by considering the array a base 2**17 number. ";
                256b   " Convert to array by considering the integer a base 256 number.   ";
                    :c " Turn character codes into characters.                            ";

1
+1, ฉันต้องการดู CJam จริงๆ น่ากลัวว่า obfuscation มากที่คุณสามารถได้รับในรหัส 22 ไบต์ที่ยังคงมีจุดมุ่งหมาย ...
Padarom

1
ทำได้ดี. มันแปลง "เอาบิตทุก 17 และเปลี่ยนเป็น 1" เป็น "" Tike vhe eöery 17 fiv และเปลี่ยน yt (เป็น c 1 "
C. Tewalt

ทำไมจึงใช้งานได้ ฉันไม่ทำตาม ..
Claudiu

1
ใช่ฉันไม่แน่ใจว่าฉันควรโพสต์นี้หรือไม่ แต่เนื่องจากคำตอบ Perl นั้นเหมือนกัน ... เสื้อคลุม Bash ที่ตอบสนองความต้องการของไฟล์ I / O จะช่วยเพิ่มจำนวนไบต์เป็น 46 มากกว่าสองเท่า แต่ก็ยังเป็นคำตอบที่สั้นที่สุด
เดนนิส

1
@ matrixugly ขอโทษ! ข้อมูลจำเพาะปล่อยให้ไฟล์ IO ของคุณมีความคลุมเครือเล็กน้อย โดยส่วนตัวฉันไม่รู้จักปัญหา เพื่อไม่ให้พิถีพิถันกับข้อดีของกล่องทราย codegolf แต่คำถามก็ถูกปิดลงและความสับสนในข้อกำหนดนี้อาจหลีกเลี่ยงได้ สนุกกับความท้าทายโดยไม่คำนึงถึง
ardnew

6

Perl 59

การทดแทน regex บนสตริงบิต:

$/=$\;$_=unpack"B*",<>;s|(.{16}).|${1}1|g;print pack"B*",$_

การใช้งาน:

perl this.pl < infile.txt > outfile.txt

endianness สามารถสลับโดยการสลับbและBในpackแม่แบบ
ardnew

2

C, 125

ถือว่า big-และ 16 บิตจำนวนเต็ม

ทำงานโดยใช้บิต - OR ทุกสองไบต์

แฟ้มใส่เป็นเอาท์พุทเป็น yz

unsigned a,b;main(c){void*f=fopen("y","r"),*g=fopen("z","w");while(b=fread(&c,1,2,f))c|=a,a?a/=2:(a=32768),fwrite(&c,1,b,g);}

Ungolfed

// The commented out /* short */ may be used if int is not 16 bits, and short is. 
unsigned /* short */ a = 0,b;
main(/* short */ c){
    void *f = fopen("y", "r"), *g = fopen("z", "w");
    while(b = fread(&c, 1, 2, f)){
      // __builtin_bswap16 may be used if you are using GCC on a little-endian machine. 
      //c = __builtin_bswap16(c);
        c |= a;
        if(a) a >>= 1;
        else a = 32768;
      //c = __builtin_bswap16(c);
        fwrite(&c, 1, b, g);
    }
}

กฎของคำถามนี้ได้รับการอัปเดตแล้ว ...
Level River St

@steveverrill และคำตอบได้รับการอัปเดตตามนั้นแล้ว
es1024

@Comintern สิ่งที่ควรเกิดขึ้นในช่วงเวลาที่การกลายเป็น 0: 00000000 00000001 00000000 00000000 10000000 00000000ดังนั้นaควรเป็นศูนย์ในบางจุด เครื่องจะต้องใช้ endian ขนาดใหญ่ (หรือมิฉะนั้นคุณจะมี00000000 10000000แทน10000000 00000000ซึ่งจะให้ค่าที่ไม่ถูกต้อง)
es1024

อืม ... ไม่เป็นไร การc = __builtin_bswap16(c);แก้ไขให้ถูกต้อง
Comintern

2

Python 2, 112 ไบต์

b=open('i').read().encode('hex')
open('o','w').write(('%x'%(int('1'+b,16)|16**len(b)/131071))[1:].decode('hex'))

ชุดนี้เป็นบิต big-endian ที่ 17 ทุกชุดเริ่มต้นที่ 17 จากจุดเริ่มต้น มันไม่ใช้ห้องสมุด มันทำงานโดยการแปลงไฟล์ป้อนข้อมูลเพื่อยักษ์nจำนวนเต็มบิตและบิต Oring 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001…กับ


1

C - 139

อ่านจากไฟล์ชื่อ "i" เอาต์พุตไปยังไฟล์ชื่อ "o"

c;main(){unsigned char b,m=1;void *i=fopen("i","r"),*o=fopen("o","w");for(;(b=fgetc(i))<129;fputc(b,o))((c+=8)%17<8)?b|=m=(m-1)?m/2:128:0;}

ด้วยตัวแบ่งบรรทัด:

c;main()
{
    unsigned char b,m=1;
    void *i=fopen("i","r"),*o=fopen("o","w");
    for(;(b=fgetc(i))<129;fputc(b,o))
        ((c+=8)%17<8)?b|=m=(m-1)?m/2:128:0;
}

นับจำนวนบิตของอินพุตและจากนั้นใช้ bitmask ลอยเพื่อตั้งค่าทุกสิบเจ็ดบิต


1

Java - 247

ใช้ a BitSetและ a loop แบบง่ายแทนที่จะจัดการ / ปิดบัง bytes ด้วยตนเอง แน่นอนว่านี่คือ java, โปรแกรมสำเร็จรูปเป็นครึ่งหนึ่งของโปรแกรมดังนั้นจึงไม่สั้นอย่างแน่นอน

ยังไม่สุดท้าย! : D

import java.util.*;import java.nio.file.*;class F{public static void main(String[]a)throws Exception{BitSet b=BitSet.valueOf(Files.readAllBytes(Paths.get(a[0])));for(int j=0;j<b.size();b.set(j),j+=17);Files.write(Paths.get("o"),b.toByteArray());}}

ไม่มีรุ่นเลื่อน:

import java.util.*;
import java.nio.file.*;
class F{
    public static void main(String[]a)throws Exception{
        BitSet b=BitSet.valueOf(Files.readAllBytes(Paths.get(a[0])));
        for(int j=0;j<b.size();b.set(j),j+=17);
        Files.write(Paths.get("o"),b.toByteArray());
    }
}

1

Python - 98 ไบต์

อ่านจาก i เขียนถึง o ใช้ไลบรารี bitarray https://pypi.python.org/pypi/bitarray

from bitarray import*;a=bitarray();a.fromfile(open('i','rb'));a[::17]=1;a.tofile(open('o','wb'))

ungolfed

from bitarray import *
a=bitarray()
a.fromfile(open('i','rb'))
a[::17]=1
a.tofile(open('o','wb'))

มันจะไม่จำเป็นต้องเป็นa[::17]=1?
undergroundmonorail

นอกจากนี้ผมเชื่อว่าคุณสามารถบันทึกไบต์ด้วยและfrom bitarray import* a=bitarray()
undergroundmonorail

0

คอบร้า - 308

use System.Text.RegularExpressions
class P
    def main
        t,b='',File.readAllBytes('x')
        for n,i in b.numbered,for l in 8,b[n]=if(l,b[n],0)+if(Regex.replace(t+='00000000'[(j=Convert.toString(i,2)).length:]+j,'.{17}',do(m as Match)='[m]'[:-1]+'1')[n*=8:n+8][7-l]<c'1',0,2**l)to uint8
        File.writeAllBytes('y',b)

ทุกครั้งที่ฉันทำอย่างใดอย่างหนึ่งเหล่านี้ 'จัดการกับความท้าทายแต่ละอย่างของบางสิ่งบางอย่าง' ฉันหวังว่าทั้ง Cobra หรือ. NET standard library จะมีตัวbinary string => integerแปลง


0

Javascript (+ HTML5), 282

อาจไม่สั้น แต่เป็นมิตรกับผู้ใช้: D

มันเป็นเบราว์เซอร์ข้าม แต่ดูเหมือนว่าโครมเป็นสิ่งเดียวที่อนุญาตเมื่อไฟล์ html เป็นไฟล์ในเครื่อง (= เข้าถึงด้วยfile://...) สำหรับเบราว์เซอร์อื่นคุณต้องวางมันไว้บนเว็บเซิร์ฟเวอร์

ไฟล์เอาต์พุตควรได้รับการบันทึกลงในไดเรกทอรีดาวน์โหลดเริ่มต้นซึ่งอาจมีพร้อมท์ไฟล์ (ขึ้นอยู่กับการกำหนดค่าของคุณ)

<input type=file onchange="r=new FileReader();r.onloadend=function(){w=window;a=new Uint8Array(r.result);for(i=17;i<a.length*8;i+=17)a[i/8>>0]|=1<<8-i%8;w.location.replace(w.URL.createObjectURL(new Blob([a],{type:'application/octet-binary'})));};r.readAsArrayBuffer(this.files[0])">

เวอร์ชันที่ไม่ถูกปรับแต่ง:

<input type=file onchange="
    var reader = new FileReader();
    reader.onloadend = function() {
        var arr = new Uint8Array(reader.result);
        for(var i = 17 ; i < arr.length * 8 ; i += 17) {
            arr[Math.floor(i / 8)] |= 1 << (8 - (i % 8));
        }
        window.location.replace(
            window.URL.createObjectURL(
                new Blob([arr], {type: 'application/octet-binary'})
            )
        );
    };
    reader.readAsArrayBuffer(this.files[0]);
">

0

Python 3 - 187 ไบต์


อ่านจากและเขียนไปio

รหัส:

o=open;j="".join;f=list(j(format(x,"08b")for x in o("i","rb").read()))
f[16::17]="1"*(len(f)//17)
with o("o","wb") as f2:f2.write(bytes(int(j(f[i*8:(i+1)*8]),2)for i in range(len(f)//8)))

Ungolfed:

# read file and convert to binary string e.g. "101010010101010101"
f = list("".join(format(x, "08b") for x in open("in.txt", "rb").read()))
# set every 17th bit to 1
f[16::17] = "1" * (len(f)//17)
with open("out.txt","wb") as f2:
    data = []
    for i in range(len(f)//8)): # for each byte
        byte = "".join(f[i*8:(i+1)*8] # get each byte
        data.append(int(byte),2) # convert to int
    f2.write(bytes(data)) # convert to byte string and write

-1

Python 3 - 103 ตัวอักษร

เปลี่ยนfเป็นพา ธ ของไฟล์ที่คุณต้องการอ่านและoไปยังพา ธ ของไฟล์ที่คุณต้องการเขียน

l=open;t=list(l(f,'r').read())
for i in range(len(t)):
 if i%18==0:t[i]='1'
l(o,'w').write(''.join(t)) 

6
มันคือทุกๆ 17 บิตไม่ใช่ไบต์
matsjoyce

1
นอกจากนี้มันคือวันที่ 17 ไม่ใช่วันที่ 18
Dennis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.