Écrivez un programme qui transforme chaque 17e bit d'un fichier texte en 1


10

Mon collègue et moi travaillons sur un logiciel hérité que nous détestons parfois. Chaque fois que vous l'exécutez, les affirmations de débogage volent partout, et ce n'est jamais une garantie que tout fonctionnera. La motivation pour cette partie de golf de code est venue de mon collègue disant ce qui suit à propos de notre logiciel .

"C'est comme chaque fois que vous exécutez ce programme, vous acceptez certaines conditions de service qui stipulent que chaque 17e bit sur votre disque dur sera transformé en 1"

Objectif: écrire un programme qui fera une copie exacte d'un fichier et transformer chaque 17e bit d'un fichier texte en 1

  • Vous ne pouvez PAS transformer CHAQUE bit du fichier en 1. C'est-à-dire que votre programme doit montrer une certaine intelligence qu'il ne cible que tous les 17 bits
  • Vous ne pouvez PAS écrire dans le fichier d'origine sous quelque forme que ce soit
  • Le gagnant est la plus petite soumission de programme à la fin du mois

Amusez-vous avec celui-ci! Aller!


7
1. Chaque question a besoin d'un critère de gain objectif. La plupart des questions sont code-golf, c'est-à-dire, le code le plus court en octets gagne. A a code-challengebesoin d'un système de notation bien spécifié. 2. La transformation de chaque 18e bit d'un disque dur en 1 n'est possible qu'en écrivant directement sur le disque. Cela ne peut pas être accompli en créant et / ou en modifiant des fichiers. 3. Faire cela rendra le disque entier inutilisable, donc une solution conforme sera destructrice. Je ne sais pas dans quelle mesure la communauté recevra une demande d'écriture de logiciels malveillants ...
Dennis

2
Je voterais pour rouvrir cette question, si seulement j'avais assez de représentants. :/
Sammitch

3
@steveverrill Je vais le changer en code golf, mais je vais le changer du 18ème au 17ème bit, pour rendre les choses intéressantes.
C. Tewalt

1
@matrixugly 17th bit est certainement plus intéressant. Gardez à l'esprit qu'il n'est pas bon de modifier les règles d'une manière qui invalide les réponses existantes (c'est pourquoi les questions sont mises en attente, afin d'éviter la publication de réponses qui rendent la question impossible à résoudre.) Cependant, la réponse existante ne fonctionne pas. ne respectez pas les autres règles en vigueur de toute façon, donc ce n'est pas un gros problème dans ce cas.
Level River St

1
Comment le fichier est-il lu? stdin?
Milo

Réponses:


9

CJam, 22 octets

q256b2H#b1f|2H#b256b:c

Essayez-le en ligne.

Touche tous les 17 bits, à partir du dernier.

J'ai utilisé STDIN et STDOUT car CJam n'a pas d'E / S de fichier. Si ce n'est pas autorisé, le programme peut être encapsulé dans un script Bash au prix de 24 octets supplémentaires:

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

Comment ça fonctionne

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, j'ai vraiment besoin de me pencher sur CJam. Génial combien d'obscurcissement vous pouvez obtenir dans un code de 22 octets qui sert toujours un but ...
Padarom

1
Bien joué. Il a converti "Prenez tous les 17 bits et transformez-le en 1" en "" Tike vhe eöery 17 fiv et tournez yt (en c 1 "
C. Tewalt

Pourquoi ça marche? Je ne suis pas ..
Claudiu

1
Oui, je ne savais pas si je devais le publier, mais comme la réponse Perl faisait essentiellement la même chose ... Un wrapper Bash pour répondre aux exigences d'E / S du fichier élèverait le nombre d'octets à 46. Plus de deux fois plus longtemps, mais toujours la réponse la plus courte.
Dennis

1
@matrixugly désolé! la spécification a laissé votre fichier IO intention un peu ambigu. personnellement, je n'ai pas reconnu de problème. ne pas continuer à insister sur les mérites du bac à sable de codegolf , mais la question se fermant et cette confusion d'exigence auraient probablement pu être évitées. apprécié le défi malgré tout
ardnew

6

Perl 59

substitution regex sur les chaînes de bits:

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

usage:

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

l'endianisme peut être basculé en basculant entre bet Bdans les packmodèles
ardnew

2

C, 125

Suppose des entiers big-endian et 16 bits .

Fonctionne en appliquant un OR au niveau du bit sur tous les deux octets.

Le fichier d'entrée est y, la sortie est 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);}

Non golfé

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

les règles sur cette question ont été mises à jour ...
Level River St

@steveverrill et la réponse a été mise à jour en conséquence
es1024

@Comintern Que devrait-il se passer au moment où a devient 0:, devrait 00000000 00000001 00000000 00000000 10000000 00000000donc aêtre nul à certains points. La machine doit utiliser du big endian (sinon vous en auriez à la 00000000 10000000place 10000000 00000000, ce qui donnerait la mauvaise valeur).
es1024

Hrm ... Tant pis. Sortir l'a c = __builtin_bswap16(c);corrigé.
Comintern

2

Python 2, 112 octets

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

Cela définit tous les 17 bits big-endian, en commençant 17e depuis le début. Il n'utilise aucune bibliothèque. Il fonctionne en convertissant le fichier d'entrée en un nentier gigantesque et en effectuant une OR au niveau du bit avec 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….


1

C - 139

Lit à partir d'un fichier nommé "i", sort dans un fichier nommé "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;}

Avec des sauts de ligne:

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

Compte les bits d'entrée, puis utilise un masque de bits flottant pour définir chaque dix-septième bit.


1

Java - 247

Utilise une BitSetet une boucle simple au lieu de gérer / masquer les octets manuellement. Bien sûr, étant Java, le passe-partout représente la moitié du programme, il n'est donc pas exactement court.

Mais pas pour la fin! :RÉ

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

Version sans défilement:

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 octets

Lisez de i, écrivez à o. Utilise la bibliothèque 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'))

non golfé

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

N'est-ce pas nécessaire a[::17]=1?
undergroundmonorail

De plus, je pense que vous pouvez enregistrer un octet avec from bitarray import*et 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)

Chaque fois que je fais l'un de ces défis «manipuler les bits individuels de quelque chose», je souhaite que Cobra ou la bibliothèque standard .NET ait un binary string => integerconvertisseur.


0

Javascript (+ HTML5), 282

Probablement pas le plus court, mais il est convivial: D

Il s'agit d'un navigateur croisé, mais il semble que Chrome soit le seul à le permettre lorsque le fichier html est un fichier local (= accès avec file://...). Pour les autres navigateurs, vous devez le mettre sur un serveur Web.

Le fichier de sortie doit être enregistré dans le répertoire de téléchargement par défaut, peut-être avec une invite de fichier (selon votre configuration).

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

Version non golfée:

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


Lit iet écrit dans 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)))

Non golfé:

# 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 caractères

Modifiez fle chemin d'accès du fichier que vous souhaitez lire et ole chemin d'accès du fichier que vous souhaitez écrire.

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
C'est tous les 17 bits, pas d'octets.
matsjoyce

1
De plus, c'est le 17e, pas le 18e.
Dennis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.