Bir metin dosyasının her 17. bitini bir dönüştüren bir program yazın 1


10

İş arkadaşım ve ben bazen nefret ettiğimiz eski bir yazılım parçası üzerinde çalışıyoruz. Her çalıştırdığınızda, hata ayıklama varsayımları her yerde uçar ve hiçbir şeyin işe yarayacağının garantisi değildir. Bu kod golf turu için motivasyon iş arkadaşımdan yazılımımız hakkında şunları söyleyerek geldi .

"Bu programı her çalıştırdığınızda, sabit diskinizdeki her 17. bitin 1'e dönüştürüleceğini söyleyen bazı hizmet şartlarını kabul ediyorsunuz"

Amaç: Bir dosyanın tam bir kopyasını yapacak bir program yazın ve bir metin dosyasının her 17 bit bir 1

  • Sen olabilir DEĞİL çevirmek HER olarak yalnızca her 17 bit hedeflediğini bazı istihbarat göstermelidir bir 1. yani sizin programa dosyanın bit
  • Sen olabilir DEĞİL herhangi bir şekilde şekil veya form orijinal dosyayı yazma
  • Kazanan ay sonunda en küçük bir program teslimiyettir

Bununla eğlenin! Git!


7
1. Her sorunun nesnel bir kazanma ölçütüne ihtiyacı vardır. Çoğu soru code-golf, yani bayttaki en kısa kod kazanır. A'nın code-challengeiyi belirlenmiş bir puanlama sistemine ihtiyacı vardır. 2. Bir sabit sürücünün her 18. bitini 1'e çevirmek yalnızca doğrudan sürücüye yazılarak mümkündür. Bu, dosyalar oluşturularak ve / veya değiştirilerek gerçekleştirilemez. 3. Bunu yapmak sürücünün tamamını kullanılamaz hale getirecektir, bu nedenle uyumlu bir çözüm yıkıcı olacaktır. Topluluğun kötü amaçlı yazılım yazma isteğini ne kadar iyi alacağını bilmiyorum ...
Dennis

2
Yeterli temsilcim olsaydı bu soruyu tekrar açmak için oy verirdim. :/
Sammitch

3
@steveverrill Golf kodunu değiştireceğim, ancak ilginç hale getirmek için 18'inci bitten 17'nci bite değiştireceğim.
C. Tewalt

1
@ matrixugly 17. bit kesinlikle daha ilginç. Kuralları, mevcut cevapları geçersiz kılacak şekilde değiştirmenin iyi bir form olmadığını unutmayın (bu yüzden, sorunun çözülmesini imkansız kılan cevapların gönderilmesini önlemek için sorular beklemeye alınır.) Ancak mevcut cevap, zaten diğer mevcut kurallara uyma, bu durumda bu büyük bir sorun değil.
Level River St

1
Dosya nasıl okunur? Stdin?
Milo

Yanıtlar:


9

CJam, 22 bayt

q256b2H#b1f|2H#b256b:c

Çevrimiçi deneyin.

Sondan sayarak her 17. bite dokunur.

CJD'de dosya G / Ç olmadığından STDIN ve STDOUT kullandım. Buna izin verilmiyorsa, program Bash komut dosyasına 24 ekstra bayt maliyetiyle sarılabilir:

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

Nasıl çalışır

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, gerçekten CJam'a bakmam gerekiyor. Hala bir amaca hizmet eden bir 22 bayt kod içine alabilirsiniz ne kadar şaşkınlık ...
Padarom

1
Aferin. Dönüştürdü "Her 17. biti alıp 1" e çevirin "" Tike vhe eöery 17. beşinci ve yt'yi (c 1'e çevirin)
C. Tewalt

Bu neden işe yarıyor? Takip etmiyorum ..
Claudiu

1
Evet, göndermem gerekip gerekmediğinden emin değildim, ancak Perl cevabı temelde aynı olduğundan ... Dosya G / Ç gereksinimlerini karşılamak için bir Bash sarıcısı bayt sayısını 46'ya yükseltir. ama yine de en kısa cevap.
Dennis

1
@matrixugly özür dilerim! spec dosya IO niyetini biraz belirsiz bıraktı. Şahsen bir konuyu tanımadım. Codegolf sandbox'ın esasına uymaya devam etmemek , ancak sorunun kapanması ve bu gereksinim karışıklığı muhtemelen önlenebilirdi. ne olursa olsun meydan zevk
ardnew

6

Perl 59

bit dizelerinde regex ikamesi:

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

kullanımı:

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

endian arasındaki geçiş yoluyla açılabilinir bve Biçinde packşablonları
ardnew

2

C, 125

Büyük endian ve 16 bit tamsayıları varsayar .

Her iki bayta bir bit-OR uygulayarak çalışır.

Girdi dosyası y, çıktı 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);
    }
}

Bu soru ile ilgili kurallar güncellendi ...
Level River St

@steveverrill ve cevabı buna göre güncellendi
es1024

@Comintern a'nın 0 olduğu zaman boyunca ne olması gerekir: 00000000 00000001 00000000 00000000 10000000 00000000dolayısıyla abelirli noktalarda sıfır olmalıdır. Makine büyük endian kullanmalıdır (ya da 00000000 10000000bunun yerine 10000000 00000000sahip olacağınız yanlış değer verir).
es1024

Hrm ... Boş ver. Çıkarma c = __builtin_bswap16(c);düzeltildi.
Comintern

2

Python 2, 112 bayt

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

Bu, her 17. büyük-endian biti 17'den başlayarak belirler. Kitaplık kullanmaz. Giriş dosyasını devasa bir nbit bit tamsayı ve bit ORing ile dönüştürerek çalışır 2**n/(2**17 - 1) == 0b10000000000000000100000000000000001….


1

C - 139

"İ" adlı bir dosyadan okur, "o" adlı bir dosyaya çıkar.

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

Satır kesmeleri ile:

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

Girdi bitlerini sayar ve her on yedinci biti ayarlamak için kayan bir bit maskesi kullanır.


1

Java - 247

Baytları BitSetelle işlemek / maskelemek yerine a ve basit bir döngü kullanır. Tabii ki bu java, kazan plakası programın yarısı, bu yüzden tam olarak kısa değil.

Yine de son değil! : 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());}}

Kaydırma yok sürüm:

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 bayt

Ben oku, o yaz. Bitarray kütüphanesini kullanır 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'))

Olması gerekmiyor a[::17]=1mu?
undergroundmonorail

Ayrıca, from bitarray import*ve ile bir bayt kaydedebileceğinize inanıyorum 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)

Bunlardan birini 'bir şeyin bireysel parçalarını manipüle' zorluklarından her yaptığımda, Cobra veya .NET standart kütüphanesinin bir binary string => integerdönüştürücü olmasını diliyorum .


0

Javascript (+ HTML5), 282

Muhtemelen en kısa değil, ancak kullanıcı dostu: D

Çapraz tarayıcı, ancak html dosyası yerel bir dosya olduğunda (= ile erişim file://...) kromun buna izin verdiği tek şey gibi görünüyor . Diğer tarayıcılar için bir web sunucusuna koymanız gerekir.

Çıktı dosyası varsayılan indirme dizinine, belki bir dosya istemiyle (yapılandırmanıza bağlı olarak) kaydedilmelidir.

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

Ungolfed sürümü:

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


'Den okur ive yazar 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)))

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 karakter

Değişim fokuyup istediğiniz dosyanın yolunu odosyasının yolunu size yazma istiyorum.

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
Her 17. bitte, bayt değil.
matsjoyce

1
Ayrıca, 17. değil 18.
Dennis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.