Viết chương trình biến mỗi bit thứ 17 của tệp văn bản thành 1


10

Đồng nghiệp của tôi và tôi làm việc trên một phần mềm kế thừa mà đôi khi chúng tôi ghét. Bất cứ khi nào bạn chạy nó, các xác nhận gỡ lỗi sẽ bay khắp nơi và không bao giờ đảm bảo rằng mọi thứ sẽ hoạt động. Động lực cho vòng golf mã này đến từ đồng nghiệp của tôi nói như sau về phần mềm của chúng tôi .

"Giống như mỗi lần bạn chạy chương trình này, bạn đồng ý với một số điều khoản dịch vụ nói rằng mỗi bit thứ 17 trên ổ cứng của bạn sẽ được chuyển thành 1"

Mục tiêu: Viết chương trình sẽ tạo một bản sao chính xác của tệp và biến mỗi bit thứ 17 của tệp văn bản thành 1

  • Bạn KHÔNG thể biến MỌI bit của tệp thành 1. tức là chương trình của bạn phải thể hiện một số thông tin rằng nó chỉ nhắm mục tiêu mỗi bit thứ 17
  • Bạn KHÔNG được ghi vào tệp gốc dưới bất kỳ hình dạng hoặc hình thức nào
  • Người chiến thắng là chương trình nhỏ nhất vào cuối tháng

Hãy vui vẻ với điều này! Đi!


7
1. Mỗi câu hỏi cần một tiêu chí chiến thắng khách quan. Hầu hết các câu hỏi là code-golf, tức là mã ngắn nhất trong byte thắng. A code-challengecần một hệ thống tính điểm được chỉ định tốt. 2. Chỉ có thể biến mọi bit thứ 18 của ổ cứng thành 1 bằng cách ghi trực tiếp vào ổ đĩa. Điều này không thể được thực hiện bằng cách tạo và / hoặc sửa đổi các tập tin. 3. Làm điều này sẽ khiến toàn bộ ổ đĩa không thể sử dụng được, vì vậy một giải pháp tuân thủ sẽ bị phá hủy. Tôi không biết cộng đồng sẽ nhận được yêu cầu viết phần mềm độc hại như thế nào ...
Dennis

2
Tôi sẽ bỏ phiếu để mở lại câu hỏi này, nếu tôi có đủ đại diện. :/
Sammitch

3
@steveverrill Tôi sẽ đổi nó thành mã golf, tuy nhiên tôi sẽ thay đổi nó từ bit thứ 18 thành bit thứ 17, để làm cho mọi thứ trở nên thú vị.
C. Tewalt

1
@matrixugly bit thứ 17 chắc chắn là thú vị hơn. Hãy nhớ rằng việc thay đổi các quy tắc theo cách vô hiệu hóa các câu trả lời hiện có là một hình thức không tốt (đó là lý do tại sao các câu hỏi được giữ lại, để tránh các câu trả lời được đăng lên khiến câu hỏi không thể sửa chữa.) Tuy nhiên, câu trả lời hiện tại không có. Dù sao cũng không tuân thủ các quy tắc hiện hành khác, vì vậy đây không phải là vấn đề lớn trong trường hợp này.
Cấp sông St

1
Làm thế nào là tập tin được đọc trong? stdin?
Milo

Câu trả lời:


9

CJam, 22 byte

q256b2H#b1f|2H#b256b:c

Hãy thử trực tuyến.

Chạm vào mỗi bit thứ 17, tính từ cuối cùng.

Tôi đã sử dụng STDIN và STDOUT vì CJam không có tệp I / O. Nếu điều đó không được phép, chương trình có thể được gói trong tập lệnh Bash với chi phí thêm 24 byte:

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

Làm thế nào nó hoạt động

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, tôi thực sự cần phải nhìn vào CJam. Thật tuyệt vời khi bạn có thể nhận được bao nhiêu mã hóa vào mã 22 byte vẫn phục vụ mục đích ...
Padarom

1
Làm tốt. Nó đã chuyển đổi "Lấy bit thứ 17 và biến nó thành 1" thành "" Tike vhe eöery fiv thứ 17 và biến yt (thành c 1 "
C. Tewalt

Tại sao điều này làm việc? Tôi không theo dõi ..
Claudiu

1
Có, tôi không chắc mình có nên đăng nó không, nhưng về cơ bản câu trả lời của Perl giống nhau ... Một trình bao bọc Bash để đáp ứng các yêu cầu I / O của tệp sẽ nâng số byte lên 46. Dài hơn gấp đôi, nhưng vẫn là câu trả lời ngắn nhất
Dennis

1
@matrixugly xin lỗi! Thông số kỹ thuật để lại tệp IO của bạn có ý định mơ hồ. Cá nhân tôi đã không nhận ra một vấn đề. không phải để tiếp tục những lợi ích của hộp cát codegolf , nhưng câu hỏi bị đóng lại và sự nhầm lẫn yêu cầu này có lẽ có thể tránh được. rất thích thách thức không phân biệt
ardnew

6

Perl 59

thay thế regex trên chuỗi bit:

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

sử dụng:

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

sự tồn tại có thể được thay đổi bằng cách chuyển đổi giữa bBtrong các packmẫu
ardew

2

C, 125

Giả sử số nguyên lớn và 16 bit .

Hoạt động bằng cách áp dụng bitwise-OR trên mỗi hai byte.

Tập tin đầu vào là y, đầu ra là z.

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

Ung dung

// 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);
    }
}

các quy tắc về câu hỏi này đã được cập nhật ...
Level River St

@steveverrill và câu trả lời đã được cập nhật tương ứng
es1024

@Comi INTERN Điều gì sẽ xảy ra vào khoảng thời gian khi a trở thành 0: 00000000 00000001 00000000 00000000 10000000 00000000do đó anên bằng 0 tại một số điểm nhất định. Máy phải sử dụng endian lớn (nếu không bạn sẽ có 00000000 10000000thay vì 10000000 00000000, sẽ cho giá trị sai).
es1024

Hrm ... Đừng bận tâm. Lấy ra c = __builtin_bswap16(c);sửa nó.
Comitern

2

Python 2, 112 byte

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

Điều này đặt tất cả các bit lớn thứ 17, bắt đầu từ 17 từ đầu. Nó không sử dụng thư viện. Nó hoạt động bằng cách chuyển đổi tệp đầu vào thành một nsố nguyên khổng lồ và OR theo bit 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….


1

C - 139

Đọc từ một tệp có tên "i", xuất ra tệp có tên "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;}

Với ngắt dòng:

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

Đếm các bit của đầu vào và sau đó sử dụng một bitmask nổi để đặt mọi bit thứ mười bảy.


1

Java - 247

Sử dụng một BitSetvà một vòng lặp đơn giản thay vì xử lý / che dấu các byte theo cách thủ công. Tất nhiên đây là java, chương trình soạn thảo là một nửa chương trình, vì vậy nó không chính xác ngắn.

Tuy nhiên, không phải là cuối cùng! : 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());}}

Phiên bản không cuộn:

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 byte

Đọc từ i, viết cho o. Sử dụng thư viện 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'))

vô dụng

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

Nó sẽ không cần phải như a[::17]=1vậy?
undergroundmonorail

Ngoài ra, tôi tin rằng bạn có thể lưu một byte với from bitarray import*a=bitarray().
undergroundmonorail

0

Rắn hổ mang - 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)

Mỗi lần tôi thực hiện một trong những điều này 'thao túng từng bit của một thử thách nào đó, tôi ước rằng thư viện tiêu chuẩn Cobra hoặc .NET có binary string => integerbộ chuyển đổi.


0

Javascript (+ HTML5), 282

Có lẽ không phải là ngắn nhất, nhưng nó thân thiện với người dùng: D

Đó là trình duyệt chéo, nhưng có vẻ như chrome là trình duyệt duy nhất cho phép khi tệp html là tệp cục bộ (= access with file://...). Đối với các trình duyệt khác, bạn cần đặt nó trên một máy chủ web.

Tệp đầu ra phải được lưu vào thư mục tải xuống mặc định, có thể bằng dấu nhắc tệp (tùy thuộc vào cấu hình của bạn).

<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])">

Phiên bản bị đánh cắp:

<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 byte


Đọc từ ivà viết cho o.

Mã số:

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)))

Ung dung:

# 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 ký tự

Thay đổi fđường dẫn của tệp bạn muốn đọc và ođường dẫn của tệp bạn muốn ghi và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
Đó là mỗi bit thứ 17, không phải byte.
matjoyce

1
Ngoài ra, đó là ngày 17, không phải ngày 18.
Dennis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.