Scrivi un programma che trasforma ogni 17 bit di un file di testo in 1


10

Il mio collega e io lavoriamo su un software legacy che odiamo a volte. Ogni volta che lo esegui, le dichiarazioni di debug arrivano ovunque, e non è mai una garanzia che qualcosa funzioni. La motivazione per questo round di codice golf è venuta dal mio collega che diceva quanto segue sul nostro software .

"È come ogni volta che esegui questo programma, accetti alcuni termini di servizio che dicono che ogni 17 bit sul tuo disco rigido verrà trasformato in 1"

Obiettivo: scrivere un programma che crei una copia esatta di un file e trasformi ogni 17 bit di un file di testo in 1

  • NON puoi trasformare OGNI bit del file in un 1. vale a dire il tuo programma deve mostrare un po 'di intelligenza che sta prendendo di mira solo ogni 17 bit
  • NON è possibile scrivere nel file originale in alcun modo forma o forma
  • Il vincitore è il più piccolo programma inviato alla fine del mese

Buon divertimento con questo! Partire!


7
1. Ogni domanda necessita di un criterio vincente oggettivo. La maggior parte delle domande sono code-golf, cioè, il codice più corto in byte vince. A ha code-challengebisogno di un sistema di punteggio ben specificato. 2. La trasformazione di ogni 18 bit di un disco rigido in 1 è possibile solo scrivendo direttamente sul disco. Ciò non può essere realizzato creando e / o modificando file. 3. In questo modo l'intera unità sarà inutilizzabile, quindi una soluzione conforme sarà distruttiva. Non so quanto bene la comunità riceverà una richiesta per scrivere malware ...
Dennis

2
Vorrei votare per riaprire questa domanda, se solo avessi abbastanza rappresentante. :/
Sammitch,

3
@steveverrill Lo cambierò in codice golf, tuttavia lo cambierò dal 18 al 17 bit, per rendere le cose interessanti.
C. Tewalt,

1
@matrixugly 17th bit è sicuramente più interessante. Tieni presente che non è una buona forma cambiare le regole in modo da invalidare le risposte esistenti (ecco perché le domande vengono messe in attesa, al fine di evitare che le risposte vengano postate che rendono impossibile risolvere la domanda.) Tuttavia la risposta esistente non Rispettare comunque le altre regole attuali, quindi non è un grosso problema in questo caso.
Level River St

1
Come viene letto il file? stdin?
Milo,

Risposte:


9

CJam, 22 byte

q256b2H#b1f|2H#b256b:c

Provalo online.

Tocca ogni 17 bit, contando dall'ultimo.

Ho usato STDIN e STDOUT poiché CJam non ha I / O di file. Se ciò non è consentito, il programma può essere racchiuso in uno script Bash al costo di 24 byte extra:

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

Come funziona

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, ho davvero bisogno di guardare in CJam. Impressionante quanta offuscamento puoi ottenere in un codice di 22 byte che ha ancora uno scopo ...
Padarom

1
Molto bene. Ha convertito "Prendi ogni 17 bit e trasformalo in 1" in "" Tike vhe eöery 17th fiv and turn yt (to c 1 "
C. Tewalt,

Perché funziona? Non seguo ..
Claudiu,

1
Sì, non ero sicuro di doverlo pubblicare, ma poiché la risposta del Perl ha fatto sostanzialmente lo stesso ... Un wrapper Bash per soddisfare i requisiti di I / O dei file eleverebbe il numero di byte a 46. Più del doppio del tempo, ma comunque la risposta più breve.
Dennis,

1
@matrixugly sorry! la specifica ha lasciato il tuo file IO intento un po 'ambiguo. personalmente non ho riconosciuto un problema. di non continuare ad arrogare i meriti della sandbox di codegolf , ma la domanda si sta chiudendo e questa confusione di requisiti probabilmente avrebbe potuto essere evitata. goduto la sfida a prescindere
ardnew

6

Perl 59

sostituzione regex su stringhe di bit:

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

utilizzo:

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

l'endianness può essere commutata passando da be Bnei packtemplate
ardnew,

2

C, 125

Presuppone numeri interi big-endian e 16 bit .

Funziona applicando un bit-OR su ogni due byte.

Il file di input è y, l'output è 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);
    }
}

le regole su questa domanda sono state aggiornate ...
Level River St

@steveverrill e la risposta ora è stata aggiornata di conseguenza
es1024,

@Comintern Cosa dovrebbe accadere nel momento in cui a diventa 0:, 00000000 00000001 00000000 00000000 10000000 00000000quindi adovrebbe essere zero in determinati punti. La macchina deve usare big endian (altrimenti avresti 00000000 10000000invece di 10000000 00000000, che darebbe il valore sbagliato).
es1024,

Hrm ... Non importa. Eliminandolo c = __builtin_bswap16(c);corretto.
Comintern,

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

Questo imposta ogni 17 bit big-endian, a partire dal 17 ° dall'inizio. Non utilizza librerie. Funziona convertendo il file di input in un nintero a bit gigantesco e ORing bit a bit con 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….


1

C - 139

Legge da un file denominato "i", genera un file chiamato "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;}

Con interruzioni di riga:

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

Conta i bit di input e quindi utilizza una maschera di bit mobile per impostare ogni diciassettesimo bit.


1

Java - 247

Utilizza un BitSetsemplice ciclo e invece di gestire / mascherare manualmente i byte. Ovviamente trattandosi di java, il boilerplate è metà del programma, quindi non è esattamente corto.

Tuttavia, non ultimo! : 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());}}

Versione senza scorrimento:

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

Leggi da i, scrivi a o. Utilizza la libreria 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'))

Non dovrebbe essere a[::17]=1?
undergroundmonorail

Inoltre, credo che puoi salvare un byte con from bitarray import*e a=bitarray().
undergroundmonorail

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)

Ogni volta che faccio una di queste sfide "manipolare i singoli bit di qualcosa", vorrei che Cobra o la libreria standard .NET avessero un binary string => integerconvertitore.


0

Javascript (+ HTML5), 282

Probabilmente non il più breve, ma è facile da usare: D

È un browser incrociato, ma sembra che Chrome sia l'unico a permetterlo quando il file html è un file locale (= accesso con file://...). Per gli altri browser, è necessario inserirlo in un server Web.

Il file di output deve essere salvato nella directory di download predefinita, magari con un prompt dei file (a seconda della configurazione).

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

Versione non golfata:

<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


Legge da ie scrive a o.

Codice:

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 caratteri

Passare fal percorso del file che si desidera leggere e oal percorso del file in cui si desidera scrivere.

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
È ogni 17 bit, non byte.
matsjoyce,

1
Inoltre, è il 17, non il 18.
Dennis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.