Escreva um programa que transforma cada 17º bit de um arquivo de texto em um 1

10

Meu colega de trabalho e eu trabalhamos em um software legado que odiamos às vezes. Sempre que você o executa, as declarações de depuração vêm voando por toda parte, e nunca é uma garantia de que algo funcione. A motivação para esta rodada de código de golfe veio do meu colega de trabalho dizendo o seguinte sobre o nosso software .

"É como se toda vez que você executasse este programa, você concordasse com alguns termos de serviço que afirmam que todo décimo sétimo bit do seu disco rígido será transformado em 1"

Objetivo: escreva um programa que faça uma cópia exata de um arquivo e transforme cada 17º bit de um arquivo de texto em 1

  • Você NÃO pode transformar CADA bit do arquivo em um 1. ou seja, seu programa deve mostrar alguma inteligência de que está direcionado apenas a cada 17 bits
  • Você NÃO pode gravar no arquivo original de nenhuma forma ou forma
  • O vencedor é o menor envio de programa no final do mês

Divirta-se com este! Vai!

C. Tewalt
fonte
7
1. Toda pergunta precisa de um critério de vitória objetivo. A maioria das perguntas é code-golf, ou seja, o código mais curto em bytes ganha. A code-challengeprecisa de um sistema de pontuação bem especificado. 2. Transformar cada 18 bits de um disco rígido em 1 só é possível escrevendo diretamente na unidade. Isso não pode ser conseguido criando e / ou modificando arquivos. 3. Isso fará com que toda a unidade seja inutilizada; portanto, uma solução compatível será destrutiva. Eu não sei o quão bem a comunidade vai receber um pedido para escrever malwares ...
Dennis
2
Eu votaria para reabrir esta pergunta, se eu tivesse representante suficiente. :/
Sammitch 4/09/14
3
@steveverrill Vou mudar para código de golfe, no entanto, vou mudar de 18 para 17 bits, para tornar as coisas interessantes.
C. Tewalt
11
@ matrixugly 17th bit certamente é mais interessante. Lembre-se de que não é uma boa forma alterar as regras de uma maneira que invalide as respostas existentes (é por isso que as perguntas são colocadas em espera, para evitar que sejam postadas respostas que impossibilitem a correção da pergunta.) No entanto, a resposta existente não cumpra outras regras atuais de qualquer maneira, portanto, não é um grande problema neste caso.
Level River St
11
Como o arquivo é lido? stdin?
Milo

Respostas:

9

CJam, 22 bytes

q256b2H#b1f|2H#b256b:c

Experimente online.

Toca a cada 17º bit, contando desde o último.

Eu usei STDIN e STDOUT desde que o CJam não possui E / S de arquivo. Se isso não for permitido, o programa pode ser agrupado em um script Bash ao custo de 24 bytes extras:

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

Como funciona

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
fonte
11
+1, eu realmente preciso pesquisar no CJam. Impressionante o quanto ofuscação você pode entrar em um código de 22 bytes que ainda serve um propósito ...
Padarom
11
Bem feito. Ele converteu "Pegue o décimo sexto bit e transforme-o em 1" em "" Tike vhe eöery 17º quinto e vire yt (para c 1 "
C. Tewalt 5/14
Por que isso funciona? Eu não sigo ..
Claudiu
11
Sim, eu não tinha certeza se deveria publicá-lo, mas como a resposta Perl fez basicamente o mesmo ... Um wrapper Bash para atender aos requisitos de E / S do arquivo elevaria a contagem de bytes para 46. Mais do que o dobro, mas ainda a resposta mais curta.
Dennis
11
@matrixugly sorry! as especificações deixaram sua intenção de E / S de arquivo um pouco ambígua. Eu, pessoalmente, não reconheci um problema. não para continuar falando sobre os méritos da caixa de areia do codegolf , mas a questão de fechar e essa confusão de requisitos provavelmente poderia ter sido evitada. gostei do desafio, independentemente
ardnew
6

Perl 59

substituição de expressões regulares em cadeias de bits:

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

uso:

perl this.pl < infile.txt > outfile.txt
novo
fonte
a ordenação pode ser alternado por comutação entre be Bnos packmodelos
ardnew
2

C, 125

Assume números inteiros big-endian e 16 bits .

Funciona aplicando um OR bit a bit em cada dois bytes.

O arquivo de entrada é y, a saída é 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
fonte
as regras sobre esta questão foram atualizadas ...
Level River St
@steveverrill ea resposta foi agora actualizado em conformidade
es1024
@ Comintern O que deve acontecer quando a torna-se 0:, 00000000 00000001 00000000 00000000 10000000 00000000portanto, adeve ser zero em determinados pontos. A máquina deve usar big endian (ou você teria em 00000000 10000000vez disso 10000000 00000000, o que daria o valor errado).
es1024
Hum ... Não importa. Tirando c = __builtin_bswap16(c);corrigido.
Comintern
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'))

Isso define cada 17º bit big endian, começando no 17º desde o início. Ele não usa bibliotecas. Ele funciona convertendo o arquivo de entrada em um nnúmero inteiro de bits gigantesco e com ORing bit a bit 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….

Anders Kaseorg
fonte
1

C - 139

Lê de um arquivo chamado "i", gera um arquivo chamado "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;}

Com quebras de linha:

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 os bits de entrada e usa uma máscara de bits flutuante para definir cada décimo sétimo bit.

Comintern
fonte
1

Java - 247

Usa um BitSete um loop simples em vez de manipular / mascarar os bytes manualmente. É claro que, sendo java, o clichê é metade do programa, portanto não é exatamente curto.

Ainda assim, não por último! : 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());}}

Versão sem rolagem:

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
fonte
1

Python - 98 bytes

Leia de i, escreva para o. Usa a biblioteca 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'))

destroçado

from bitarray import *
a=bitarray()
a.fromfile(open('i','rb'))
a[::17]=1
a.tofile(open('o','wb'))
user590028
fonte
Não precisaria ser a[::17]=1?
Undergroundmonorail
Além disso, acredito que você pode salvar um byte com 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)

Toda vez que faço um desses desafios de "manipular os bits individuais de algo", desejo que o Cobra ou a biblioteca padrão do .NET possuam um binary string => integerconversor.

Furioso
fonte
0

Javascript (+ HTML5), 282

Provavelmente não é o mais curto, mas é fácil de usar: D

É um navegador cruzado, mas parece que o chrome é o único que permite quando o arquivo html é um arquivo local (= acessar com file://...). Para os outros navegadores, você precisa colocá-lo em um servidor web.

O arquivo de saída deve ser salvo no diretório de download padrão, talvez com um prompt de arquivos (dependendo da sua configuração).

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

Versão não destruída:

<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
fonte
0

Python 3-187 bytes


ie escreve para o.

Código:

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
fonte
-1

Python 3-103 caracteres

Mude fpara o caminho do arquivo que você deseja ler e opara o caminho do arquivo em que deseja gravar.

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 Decay
fonte
6
É a cada 17 bits, não byte.
matsjoyce
11
Além disso, é 17, não 18.
Dennis