Napisz program, który zamienia co 17 bit pliku tekstowego na 1


10

Mój współpracownik i ja pracujemy nad starszym oprogramowaniem, którego czasem nienawidzimy. Za każdym razem, gdy go uruchamiasz, wszędzie pojawiają się potwierdzenia debugowania i nigdy nie jest to gwarancją, że coś zadziała. Motywacja do tej rundy golfa kodu pochodzi od mojego współpracownika mówiącego o naszym oprogramowaniu .

„To tak, jakbyś za każdym razem uruchamiał ten program, zgadzasz się na niektóre warunki usługi, które mówią, że co 17 bitów na dysku twardym zmieni się w 1”

Cel: Napisz program, który utworzy dokładną kopię pliku i zamieni każdy 17-bitowy plik tekstowy w 1

  • NIE możesz zmienić KAŻDEJ części pliku na 1. tzn. Twój program musi wykazywać pewną inteligencję, że celuje tylko co 17 bitów
  • NIE możesz pisać do oryginalnego pliku w jakikolwiek sposób
  • Zwycięzca jest najmniejszym przedstawieniu programu na koniec miesiąca

Baw się dobrze z tym! Udać się!


7
1. Każde pytanie wymaga obiektywnego kryterium wygranej. Większość pytań to code-golfnp. Wygrywa najkrótszy kod w bajtach. code-challengePotrzebuje dobrze określony system punktacji. 2. Przekształcanie co 18 bitów dysku twardego w 1 jest możliwe tylko poprzez bezpośrednie zapisywanie na dysku. Nie można tego osiągnąć, tworząc i / lub modyfikując pliki. 3. W ten sposób cały dysk stanie się bezużyteczny, więc zgodne z nim rozwiązanie będzie destrukcyjne. Nie wiem, jak dobrze społeczność otrzyma prośbę o napisanie złośliwego oprogramowania ...
Dennis,

2
Głosowałbym, aby ponownie otworzyć to pytanie, gdybym tylko miał wystarczająco dużo przedstawicieli. :/
Sammitch,

3
@steveverrill Zamienię go na kod golfa, jednak zamierzam zmienić go z 18 na 17, aby uczynić rzeczy interesującymi.
C. Tewalt

1
@matrixugly 17. bit z pewnością jest bardziej interesujący. Należy pamiętać, że zmiana zasad w sposób, który unieważnia istniejące odpowiedzi, jest nieodpowiednia (dlatego pytania są zawieszane, aby uniknąć zamieszczania odpowiedzi uniemożliwiających naprawienie pytania). Jednak istniejąca odpowiedź nie pozwala i tak nie są zgodne z innymi obowiązującymi zasadami, więc w tym przypadku nie jest to duży problem.
Level River St.

1
Jak wczytuje się plik? stdin?
Milo

Odpowiedzi:


9

CJam, 22 bajty

q256b2H#b1f|2H#b256b:c

Wypróbuj online.

Dotyka co 17 bitów, licząc od ostatniego.

Użyłem STDIN i STDOUT, ponieważ CJam nie ma plików I / O. Jeśli nie jest to dozwolone, program może zostać zawinięty w skrypt Bash kosztem 24 dodatkowych bajtów:

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

Jak to działa

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, naprawdę muszę zajrzeć do CJam. Niesamowite, ile zaciemnienia można uzyskać w 22-bajtowym kodzie, który wciąż spełnia swoje zadanie ...
Padarom

1
Dobra robota. Przekształcił „Weź co 17 bitów i zamień na 1” w „” Tike vhe eöery 17. fiv i obróć yt (do c 1 ”
C. Tewalt

Dlaczego to działa? Nie śledzę ..
Claudiu

1
Tak, nie byłem pewien, czy powinienem to opublikować, ale ponieważ odpowiedź Perla była w zasadzie taka sama ... Opakowanie Bash spełniające wymagania we / wy pliku podniosłoby liczbę bajtów do 46. Ponad dwa razy dłużej, ale wciąż najkrótsza odpowiedź.
Dennis

1
@matrixugly przepraszam! specyfikacja pozostawiła twoją intencję IO pliku trochę niejednoznaczną. osobiście nie rozpoznałem problemu. żeby nie przestawać czerpać z zalet piaskownicy codegolf , ale pytanie się zamknęło i tego pomieszania wymagań prawdopodobnie można było uniknąć.
mimo wszystko

6

Perl 59

Podstawienie wyrażenia regularnego na ciągach bitów:

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

stosowanie:

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

endianizm można przełączać, przełączając się między szablonami bi pomiędzy Bnimipack
nowy

2

C 125

Przyjmuje liczby całkowite big-endian i 16-bitowe .

Działa poprzez zastosowanie bitowego-LUB na co dwa bajty.

Plik wejściowy to y, wyjście to 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);}

Nie golfił

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

zasady dotyczące tego pytania zostały zaktualizowane ...
Level River St

@steveverrill, a odpowiedź została teraz odpowiednio zaktualizowana
es1024

@Comintern Co powinno się zdarzyć w czasie, gdy a staje się 0: a 00000000 00000001 00000000 00000000 10000000 00000000zatem aw niektórych punktach powinno wynosić zero. Maszyna musi używać big endian (w przeciwnym razie miałbyś 00000000 10000000zamiast tego 10000000 00000000, co dałoby niewłaściwą wartość).
es1024

Hrm ... Nieważne. Wyjęcie c = __builtin_bswap16(c);poprawiło to.
Comintern

2

Python 2, 112 bajtów

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

Ustawia to co 17 bit big-endian, zaczynając od 17 od początku. Nie używa bibliotek. Działa poprzez konwersję pliku wejściowego na gigantyczną n-bitową liczbę całkowitą i bitowe ORowanie za pomocą 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….


1

C - 139

Odczytuje z pliku o nazwie „i”, wyprowadza do pliku o nazwie „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;}

Z podziałami linii:

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

Zlicza bity wejściowe, a następnie używa pływającej maski bitowej do ustawiania co siedemnaście bitów.


1

Java - 247

Używa BitSetprostej pętli zamiast ręcznej obsługi / maskowania bajtów. Oczywiście, ponieważ jest to Java, płyta kotła stanowi połowę programu, więc nie jest dokładnie krótka.

Nadal nie ostatni! :RE

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

Wersja bez przewijania:

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 bajtów

Przeczytaj od i, napisz do o. Wykorzystuje bibliotekę 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'))

bez golfa

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

Czy nie musiałoby tak być a[::17]=1?
undergroundmonorail

Wierzę też, że możesz uratować bajt za pomocą from bitarray import*i a=bitarray().
undergroundmonorail

0

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

Za każdym razem, gdy wykonuję jedno z tych wyzwań „manipulowania poszczególnymi kawałkami czegoś”, żałuję, że ani Cobra, ani standardowa biblioteka .NET nie miały binary string => integerkonwertera.


0

JavaScript (+ HTML5), 282

Prawdopodobnie nie najkrótszy, ale przyjazny dla użytkownika: D

Jest to przeglądarka internetowa, ale wydaje się, że Chrome jest jedynym, który pozwala na to, gdy plik HTML jest plikiem lokalnym (= dostęp za pomocą file://...). W przypadku innych przeglądarek musisz umieścić go na serwerze WWW.

Plik wyjściowy należy zapisać w domyślnym katalogu pobierania, być może z monitem o plik (w zależności od konfiguracji).

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

Wersja bez golfa:

<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 bajtów


Wczytuje ii zapisuje do o.

Kod:

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

Nie golfowany:

# 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 znaków

Przejdź fdo ścieżki pliku, który chcesz przeczytać, i ościeżki pliku, w którym chcesz zapisać.

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
To co 17 bitów, a nie bajtów.
matsjoyce

1
Poza tym jest 17, a nie 18.
Dennis
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.