Schreiben Sie ein Programm, das jedes 17. Bit einer Textdatei in eine 1 umwandelt

10

Mein Kollege und ich arbeiten an einer alten Software, die wir manchmal hassen. Wann immer Sie es ausführen, fliegen Debug-Asserts überall hin und es ist nie eine Garantie dafür, dass irgendetwas funktioniert. Die Motivation für diese Runde Code-Golf kam von meinem Kollegen, der Folgendes über unsere Software sagte .

"Es ist, als ob Sie jedes Mal, wenn Sie dieses Programm ausführen, einigen Nutzungsbedingungen zustimmen, die besagen, dass jedes 17. Bit auf Ihrer Festplatte in eine 1 umgewandelt wird."

Ziel: Schreiben Sie ein Programm, das eine exakte Kopie einer Datei erstellt und jedes 17. Bit einer Textdatei in eine 1 verwandelt

  • Sie können nicht drehen EVERY Bit der Datei zu einem 1. dh Ihr Programm muss eine gewisse Intelligenz zeigen , dass es nur jedes 17. Bit Targeting
  • Sie dürfen NICHT in irgendeiner Form in die Originaldatei schreiben
  • Der Gewinner ist die kleinste Programmeinreichung am Monatsende

Viel Spaß damit! Gehen!

C. Tewalt
quelle
7
1. Jede Frage benötigt ein objektives Gewinnkriterium. Die meisten Fragen sind code-golf, dh kürzester Code in Bytes gewinnt. A code-challengebenötigt ein genau festgelegtes Bewertungssystem. 2. Das Verwandeln jedes 18. Bits einer Festplatte in eine 1 ist nur durch direktes Schreiben auf die Festplatte möglich. Dies kann nicht durch Erstellen und / oder Ändern von Dateien erreicht werden. 3. Wenn Sie dies tun, wird das gesamte Laufwerk unbrauchbar, sodass eine kompatible Lösung destruktiv ist. Ich weiß nicht, wie gut die Community eine Anfrage zum Schreiben von Malware erhalten wird ...
Dennis
2
Ich würde dafür stimmen, diese Frage erneut zu eröffnen, wenn ich nur genug Vertreter hätte. :/
Sammitch
3
@steveverrill Ich werde es in Code Golf ändern, aber ich werde es vom 18. auf das 17. Bit ändern, um die Dinge interessant zu machen.
C. Tewalt
1
@matrixugly 17. Bit ist sicherlich interessanter. Denken Sie daran, dass es keine gute Form ist, die Regeln so zu ändern, dass vorhandene Antworten ungültig werden (aus diesem Grund werden Fragen zurückgestellt, um zu vermeiden, dass Antworten veröffentlicht werden, die eine Behebung der Frage unmöglich machen.) Die vorhandene Antwort ist jedoch nicht gültig Ich halte mich sowieso nicht an andere aktuelle Regeln, daher ist dies in diesem Fall kein großes Problem.
Level River St
1
Wie wird die Datei eingelesen? stdin?
Milo

Antworten:

9

CJam, 22 Bytes

q256b2H#b1f|2H#b256b:c

Probieren Sie es online aus.

Berührt jedes 17. Bit und zählt vom letzten.

Ich habe STDIN und STDOUT verwendet, da CJam keine Datei-E / A hat. Wenn dies nicht zulässig ist, kann das Programm zum Preis von 24 zusätzlichen Bytes in ein Bash-Skript eingeschlossen werden:

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

Wie es funktioniert

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.                            ";
Dennis
quelle
1
+1, ich muss mich wirklich mit CJam befassen. Genial, wie viel Verschleierung Sie in einen 22-Byte-Code bekommen können, der immer noch einen Zweck
erfüllt
1
Gut gemacht. Es wandelte "Nehmen Sie das alle 17. Bit und verwandeln Sie es in eine 1" in "" Tike vhe eöery 17. fiv und drehen Sie yt (zu c 1 "
C. Tewalt
Warum funktioniert das? Ich folge nicht ..
Claudiu
1
Ja, ich war mir nicht sicher, ob ich es veröffentlichen sollte, aber da die Perl-Antwort im Grunde dasselbe tat ... Ein Bash-Wrapper zur Erfüllung der Datei-E / A-Anforderungen würde die Anzahl der Bytes auf 46 erhöhen. Mehr als doppelt so lang, aber immer noch die kürzeste Antwort.
Dennis
1
@matrixugly sorry! Die Spezifikation hat Ihre Datei-E / A-Absicht ein wenig mehrdeutig gemacht. Ich persönlich habe kein Problem erkannt. nicht weiter über die Vorzüge des Codegolf- Sandkastens zu harpen , aber die Frage, die geschlossen wurde, und diese Anforderungsverwirrung hätten wahrscheinlich vermieden werden können. genossen die Herausforderung
trotzdem
6

Perl 59

Regex-Substitution für Bit-Strings:

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

Verwendungszweck:

perl this.pl < infile.txt > outfile.txt
ardnew
quelle
Die Endianness kann durch Umschalten zwischen bund Bin den packVorlagen
umgeschaltet werden
2

C 125

Nimmt Big-Endian- und 16-Bit-Ganzzahlen an .

Funktioniert, indem alle zwei Bytes ein bitweises ODER angewendet wird.

Eingabedatei ist y, Ausgabe ist 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);}

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);
    }
}
es1024
quelle
Regeln für diese Frage wurden aktualisiert ...
Level River St
@steveverrill und die Antwort wurde jetzt entsprechend aktualisiert
es1024
@Comintern Was die Zeit geschehen um sollte , wenn eine 0 wird: 00000000 00000001 00000000 00000000 10000000 00000000, also asollte Null an bestimmten Punkten sein. Die Maschine muss Big Endian verwenden (sonst hätten Sie 00000000 10000000stattdessen 10000000 00000000, was den falschen Wert ergeben würde).
Es1024
Hrm ... Egal. Herausnehmen c = __builtin_bswap16(c);korrigierte es.
Komintern
2

Python 2, 112 Bytes

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

Dies setzt jedes 17. Big-Endian-Bit, beginnend mit dem 17. von Anfang an. Es werden keine Bibliotheken verwendet. Es funktioniert durch Konvertieren der Eingabedatei in eine gigantische n-bit-Ganzzahl und bitweises ODER-Verknüpfen mit 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….

Anders Kaseorg
quelle
1

C - 139

Liest aus einer Datei mit dem Namen "i" und gibt in eine Datei mit dem Namen "o" aus.

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

Mit Zeilenumbrüchen:

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

Zählt Eingangsbits und verwendet dann eine schwebende Bitmaske, um jedes siebzehnte Bit zu setzen.

Komintern
quelle
1

Java - 247

Verwendet eine BitSetund eine einfache Schleife, anstatt die Bytes manuell zu behandeln / zu maskieren. Da dies Java ist, ist das Boilerplate natürlich das halbe Programm, also nicht gerade kurz.

Immer noch nicht zuletzt! : 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());}}

No-Scroll-Version:

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());
    }
}
Geobits
quelle
1

Python - 98 Bytes

Lesen Sie von i, schreiben Sie an o. Verwendet die Bitarray-Bibliothek 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'))
user590028
quelle
Wäre es nicht nötig a[::17]=1?
U-Bahn:
Ich glaube auch, dass Sie mit from bitarray import*und ein Byte speichern können a=bitarray().
U-Bahn:
0

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

Jedes Mal, wenn ich eine dieser Herausforderungen zum "Manipulieren der einzelnen Teile von etwas" durchführe, wünsche ich mir, dass entweder Cobra oder die .NET-Standardbibliothek einen binary string => integerKonverter haben.

Οurous
quelle
0

Javascript (+ HTML5), 282

Wahrscheinlich nicht die kürzeste, aber benutzerfreundlich: D.

Es ist browserübergreifend, aber es scheint, dass Chrome das einzige ist, das es zulässt, wenn die HTML-Datei eine lokale Datei ist (= Zugriff mit file://...). Für die anderen Browser müssen Sie es auf einem Webserver ablegen.

Die Ausgabedatei sollte im Standard-Download-Verzeichnis gespeichert werden, möglicherweise mit einer Eingabeaufforderung (abhängig von Ihrer Konfiguration).

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

Ungolfed Version:

<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]);
">
sebcap26
quelle
0

Python 3 - 187 Bytes


Liest ein iund schreibt an o.

Code:

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
matsjoyce
quelle
-1

Python 3 - 103 Zeichen

Wechseln Sie fin den Pfad der Datei, die Sie lesen möchten, und oin den Pfad der Datei, in die Sie schreiben möchten.

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)) 
Beta-Zerfall
quelle
6
Es ist jedes 17. Bit, kein Byte.
Matsjoyce
1
Es ist auch der 17. und nicht der 18 ..
Dennis