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.