Dize kod çözme


41

Bu benim ppcg'deki ilk görevim!

Giriş

İki farklı ascii karakterinden oluşan bir dize. Örneğin

ABAABBAAAAAABBAAABAABBAABA

Meydan okuma

Görev bu kuralları aşağıdaki kurallara uyarak çözmek:

  1. İlk iki karakteri atla
  2. Dizenin geri kalanını 8 karakterden oluşan gruplara ayırın
  3. Her grupta, her karakteri, 0bu karakter orijinal dizgenin ilk karakteriyle aynıysa, 1aksi takdirde
  4. Şimdi her grup bir baytı temsil ediyor. Her grubu bayt char kodundan karaktere dönüştürün
  5. Tüm karakterleri birleştir

Örnek

Yukarıdaki dizginin kodunu çözelim.

 AB  AABBAAAA  AABBAAAB  AABBAABA
 ^^     ^         ^         ^
 |      |         |         |
 |      \---------|---------/
 |                |
Skip      Convert to binary

Uyarı Aorijinal dizisindeki ilk karakter ve Bikincisidir. Bu nedenle, her yerini Aile 0ve her Bile 1. Şimdi biz elde ediyoruz:

00110000  00110001  00110010

ki bu [0x30, 0x31, 0x32]ikilidir. Bu değerler ["0", "1", "2"]sırasıyla karakterleri temsil eder , bu nedenle son çıktı olması gerekir 012.

puanlama

Bu, elbette, , bu da kodunuzu mümkün olduğu kadar kısa yapmak anlamına gelir. Puan bayt cinsinden ölçülür.

Kısıtlamalar ve GÇ formatı

Standart kurallar geçerlidir. İşte bazı ek kurallar:

  • Geçerli bir girdi kabul edebilirsiniz
    • Giriş dizesi tam olarak iki farklı karakterden oluşur.
    • İlk iki karakter farklı
    • Giriş dizesinin minimum uzunluğu 2 karakterdir.
    • Uzunluk her zaman 2 modulo 8 verecektir
  • Dize her zaman yalnızca yazdırılabilir ASCII karakterlerinden oluşacağını varsayabilirsiniz.
    • Hem girdi hem de kod çözülmüş dizede
  • Lider ve takip eden boşluklara çıktıda izin verilir (eşleşen her şey /\s*/)

5
Adamım, ilk meydan okuma için, bu gördüğüm en iyi biçimlendirilmiş zorluklardan biri. Bilgilendirici olarak, topluluk sanal alanı , göndermeden önce geri bildirim almak için harika bir yerdir, bu nedenle tanımadığınız bir kural için rasgele tekrarlanamazsınız.
Magic Octopus Urn

@MagicOctopusUrn. Teşekkür ederim! Sandbox hakkında bir şey bilmiyordum, bir dahaki sefere oraya gönderirim :)

2
Çoğunlukla kullanıyorum, insanlar beni tekrarlayan sorularla çağırabilirler, kurallara uymaları çok basit, oldukça metaları ezberlemeden sikikleri bilmek :). Ben de sohbet odalarını kontrol etmenizi öneririm, öğrenmeyi umduğunuz hemen hemen her dilde sohbetlerimiz var ve sorularınız teşvik ediliyor.
Magic Octopus Urn

1
Büyük ilk meydan okuma! Bazı daha fazla test vakası temiz olur.
Lynn,

Gerçekten güzel ilk meydan okuma. Bununla oynamaktan eğlendim.
ElPedro

Yanıtlar:



8

Stax , 15 11 bayt

ó║¥U⌂½íèäöñ

Koşun ve staxlang.xyz de hata ayıklayın!

Hızlı 'n' kirli yaklaşım. Bunu geliştirmek için çalışmak. Geliştirilmiş!

Ambalajsız (13 bayt) ve açıklama

2:/8/{{[Im:bm
2:/              Split at index 2. Push head, then tail.
   8/            Split into length-8 segments.
     {      m    Map block over each segment:
      {  m         Map block over each character:
       [             Copy first two elements (below) in-place.
        I            Index of character in first two characters.
          :b       Convert from binary.
                 Implicit print as string.

Ahhhh ... Bunun bizi yeneceğini biliyordum.
Magic Octopus Urn

6

JavaScript (Node.js) , 67 bayt

s=>s.replace(/./g,x=(c,i)=>(x=x*2|c==s[1],Buffer(i<3|i&7^1?0:[x])))

Çevrimiçi deneyin!

Nasıl?

Yapıcının iki farklı sözdizimini kullanıyoruz Buffer:

  • Buffer([n])tek bir bayt içeren bir tampon oluşturur , n ve karşılık gelen ASCII karakter zorlama bir. Sadece 8 en az anlamlı bit n dikkate alınır.
  • Buffer(n)n baytlık bir tampon üretir . Bu nedenle, Buffer(0)boş bir dizeye zorlanan boş bir tampon oluşturur.

Not: Her ikisi de son Düğüm sürümlerinde kullanımdan kaldırılmıştır. Buffer.from([n])ve Buffer.alloc(n)bunun yerine kullanılmalıdır.

Yorumlananlar

s =>                   // given the input string s
  s.replace(/./g, x =  // initialize x to a non-numeric value (will be coerced to 0)
    (c, i) => (        // for each character c at position i in s:
      x = x * 2 |      //   shift x to the left
          c == s[1],   //   and append the new bit, based on the comparison of c with s[1]
      Buffer(          //   invoke the constructor of Buffer (see above):
        i < 3 |        //     if i is less than 3
        i & 7 ^ 1 ?    //     or i is not congruent to 1 modulo 8:
          0            //       replace c with an empty string
        :              //     else:
          [x]          //       replace c with the ASCII char. whose code is the LSB of x
      )                //   end of Buffer constructor
  ))                   // end of replace(); return the new string

6

bash, 59 58 52 bayt

tr -t "$1" 01 <<<$1|cut -c3-|fold -8|sed 'i2i
aP'|dc

Çevrimiçi deneyin!

İnekler, 6 bayt tasarrufu için quack sayesinde .

Bu zorluk, bir dizi coreutil ile (ve dcsonunda dönüşümü ve çıktının yapılması) oldukça iyi çalışıyor . İlk önce kullanırız

tr -t "$1" 01 <<<$1

Girişteki iki karakteri sıfıra ve birine çevirmek için. -tBuna girişte ilk iki karakter transliterating için azaltır böylece bayrak, ikinci uzunluğuna ilk argüman keser 0ve 1ne istediğimizi olan. Sonra,

cut -c3-

ilk iki karakteri siler ve

fold -8

Her satırda 8 karakter çıktısı. Son olarak, sedkomut her satırı dcsayıyı ikili olarak okuyan ve bu baytı çıktı olarak alan bir parçacık içine dönüştürür .


Bir bash cevabını görmek her zaman güzeldir :) Her bir satırı, her karakteri yazdıran dc koduna dönüştürerek ve ardından dc tio.run/##S0oszvj/… (ve sonra boşluk cut -ckaldırılabilir)
Kritixi Lithos

6

Amstrad CPC'de Z80 makine kodu, 32 31 30 bayt

000001  0000  (9000)        ORG &9000
000002  9000  EB            EX DE, HL
000003  9001  46            LD B, (HL)
000004  9002  23            INC HL
000005  9003  5E            LD E, (HL)
000006  9004  23            INC HL
000007  9005  56            LD D, (HL)
000009  9006  1A            LD A, (DE)
000010  9007  05            DEC B
000011  9008  13            INC DE
000012  9009  4F            LD C, A
000014  900A                Light
000015  900A  26 01         LD H, &01
000016  900C                Last
000017  900C  13            INC DE
000018  900D  05            DEC B
000019  900E  C8            RET Z
000021  900F                Loop
000022  900F  1A            LD A, (DE)
000023  9010  B9            CP C
000024  9011  28 01         JR Z, Lable
000025  9013  37            SCF
000026  9014                Lable
000027  9014  ED 6A         ADC HL, HL
000028  9016  30 F4         JR NC, Last
000029  9018  7D            LD A, L
000030  9019  CD 5A BB      CALL &BB5A
000032  901C  18 EC         JR Light

Kod, her karakterin yerine 0, bu karakter orijinal dizginin ilk karakteriyle aynıysa ve 1aksi takdirde kelimenin tam anlamıyla değiştirildiyse ve karakterin girdi dizisindeki ikinci karakterle eşleştiğini kontrol etmek için hiç zahmete girmiyorsa , talimatı alır . Sadece ilk karakterle aynı ve ilk karakterden farklı olanları kontrol eder.

Ben kayıtlar (Z80 sadece, gerisi ihtiyaç uzun talimatları 7 kolaylıkla kullanılabilen 8 bit saklayıcı mevcuttur) Ben koymak böylece bitti &01de Hkullanarak birlikte LASCII karakter oluşturmak için (Ben sadece başlatılması biraz gereksiz olduğunu fark L, bir bayt tasarrufu ). Ne zaman HCarry bayrağına taşar, karakter Lçıktı olmaya hazırdır. Neyse ki, bir 16-bit vardır ADC( İlan ile d C sol kaydırma talimatının işi yapar Arry).

(DE)Herhangi bir 8-bitlik kayıt defterine okunabilmesine Arağmen sadece okunabilir (HL), bu yüzden hangisinin kullanılacağı konusunda bir uzlaşma oldu. Ben karşılaştırmak olamazdı (DE)ile Cİçine bir tane yüklemek zorunda doğrudan Ailk. Etiketler L(ile bir araya getirme gereksinimi) ile başlayan rasgele kelimelerdir .

  • A Akümülatör - karşılaştırma yapabilen tek kayıt
  • Bsayaç yazmacı talimatı için DJNZ: D ecrement ( B) ve J UMP ise N ile Z ERO . Kodu yeniden düzenleyerek, DJNZdaha az sayıda baytla işini yaptım
  • C giriş dizesindeki ilk karakter
  • D, EOlarak DEgeçerli giriş karakterin adresi
  • H taşıma tetiği (her 8 döngü)
  • L çıkış karakteri oluşturuluyor

görüntü tanımını buraya girin


6

05AB1E , 10 bayt

¦¦Sk8ôJCçJ

Çevrimiçi deneyin!

-3 emigna sayesinde.


Ù             # Unique letters, in order they appear.
 v            # For each...
  yN:         # Push letter and index, replace in input.
     }        # End loop.
      ¦¦      # Remove first x2.
        8ô    # Split into eighths.
          C   # Convert to integer.
           ç  # Convert to char.
            J # Join together entire result.

1
01‡Döngü yerine kullanabilirsiniz . EDIT: ya da daha iyisi:¦¦Sk8ôJCçJ
Emigna


5

J, 17 13 Bayt

u:_8#.\2}.1{=

-4 FrownyFrog sayesinde

Eski versiyon:

u:_8#.\2&({.i.}.)

Açıklama:

u:_8#.\2}.1{=
            =  | Self classify, for each unique element x of y, compute x = y, element-wise
          1{   | Second row
       2}.     | Drop 2
  _8#.\        | Convert non-intersecting subarrays of length 8 from binary
u:             | Convert to characters

Örnekler:

   = 'ABAABBAAAAAABBAAABAABBAABA'
1 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 0 1
0 1 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0

   2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0

   _8#.\2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
48 49 50

   u:_8#.\2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
012

1
2}.1{=4 bayt kaydetmek için.
FrownyFrog

Oh, bağlıyım ... Başka bir bayt bulamıyorum.
Magic Octopus Urn

1
@MagicOctopusUrn aslında bir snippet, [:başında bir olmalı :)
FrownyFrog 23:18


5

R , 71 bayt

function(s)intToUtf8(2^(7:0)%*%matrix((y=utf8ToInt(s))[-1:-2]==y[2],8))

Çevrimiçi deneyin!

Şaşırtıcı bir şekilde golf!

İlk olarak, dizeyi ascii kod-noktalarına dönüştürerek utf8ToIntkaydeder y. Negatif endeksleme ile ilk iki karakter Çıkarma kullanmaktan daha kısadır tail.

Dizi (matris çarpımı) uygulandığında y[-1:-2]==y[2]bitlere eşdeğerdir %*%, ancak önce bu diziyi bir doğrusal diziden bayt gruplarına dönüştürerek bir matrixile yeniden şekillendiririz nrow=8. Neyse ki, daha sonra 2 uygun güçleri ile matris çarpımını kullanarak ascii kod noktalarına 2^(7:0)dönüştürebiliriz ve sonra kod noktalarını tekrar bir dizgeye dönüştürürüz intToUtf8.



4

PHP, 73 71 bayt

while($s=substr($argn,-6+$i+=8,8))echo~chr(bindec(strtr($s,$argn,10)));

Pipe ile çalıştırın -nRveya çevrimiçi deneyin .

golfings:

  • dizini başlatmak -6ve arttırmak8
  • strtruzun parametrede aşırı karakterleri görmezden gelen istismar ( substrgerekli değil)
  • çeviri 10ve sonra ters çevirmek için alıntı gerekmez -> -1 bayt
  • ascii kodu yerine invert karakteri -> ~sözcük sınırı -> -1 bayt olarak işlev görür.

3
En azından beynini eşleştirmelisin:for(;$s=substr($argn,2+8*$i++,8);)echo~chr(bindec(strtr($s,$argn,10)));
Christoph

2
@Christoph Brainfuck'un aniden makul bir cevap uzunluğu için bir standart olmasını seviyorum.
Nit

4

Pyth, 20 9 bayt

CittxLQQ2

FryAmTheEggman sayesinde 11 bayt kaydedildi.

Burada dene

açıklama

CittxLQQ2
    xLQQ    Find the index of each character in the string.
  tt        Exclude the first 2.
 i      2   Convert from binary.
C           Get the characters.

@FryAmTheEggman Teşekkürler. Açıkçası Pyth hakkında daha çok şey öğreneceğim var.
Anma

Haha, ben de öyleyim! Çok karmaşık bir golf dili. Umarım içinde golf oynamaya devam edersiniz :)
FryAmTheEggman

3

Ruby , 82 79 bayt

->s{s[2..-1].tr(s[0,2],'01').chars.each_slice(8).map{|s|s.join.to_i(2).chr}*''}

Çevrimiçi deneyin!


1
PPCG'ye Hoşgeldiniz! Benimkini göndermeden önce Ruby'de zaten bir cevap olduğunu görmedim, ancak bazı tipik golf püf noktaları da sizin yaklaşımınıza uygulanır - örneğin, sonuncusu ve tarafından .joindeğiştirilebilir . *''s[0..1]s[0,2]
Kirill L.

3

Japt, 11 bayt

¤£bXÃò8 ®Íd

Dene


açıklama

¤               :Slice from the 3rd character
 £  Ã           :Map over each X
  bX            :  Get the first 0-based index of X in the input
     ò8         :Split to an array of strings of length 8
        ®       :Map
         Í      :  Convert from base-2 string to base-10 integer
          d     :  Get the character at that codepoint

s2Kısayolun çok akıllıca kullanımı , güzel.
Nit

3

PHP + GNU Çoklu Hassasiyet, 63 61

<?=gmp_export(gmp_init(substr(strtr($argn,$argn,"01"),2),2));

maalesef GMP eklentisi varsayılan olarak aktif değil (ancak gönderildi).

Bu şekilde koş:

echo "ABABABAAAAABABAAAAAABAABBAABAAAABBABAAABBB" | php -F a.php

<?=2 bayt ve muhtemelen gün kazandırır. ;-)
Titus

@Titus evet, fakat ne yazık ki işe yaramadı -R(denedim)
Christoph

1
-Fbunun yerine deneyin
Titus


3

Java 8, 143 142 141 bayt

s->{char i=47;for(;++i<50;)s=s.replace(s.charAt(i%2),i);for(i=2;i<s.length();)System.out.print((char)Long.parseLong(s.substring(i,i+=8),2));}

@ OlivierGrégoire sayesinde -1 bayt .

Çevrimiçi deneyin.

Açıklama:

s->{                            // Method with String parameter and no return-type
  char i=47;                    //  Index character, starting at 47
  for(;++i<50;)                 //  Loop 2 times
    s.replace(s.charAt(i%2),i)  //   Replace first characters to 0, second characters to 1
  for(i=2;i<s.length();)        //  Loop `i` from 2 upwards over the String-length
    System.out.print(           //   Print:
     (char)                     //    As character:
      Long.parseLong(           //     Convert Binary-String to number
       s.substring(i,i+=8)      //      The substring in range [i,i+8),
      ,2));}



2

APL + WIN, 30 bayt

Dizin kökeni 0. Dize girişi için bilgi istemi

⎕av[2⊥¨(+\0=8|⍳⍴b)⊂b←2↓s≠↑s←⎕]

Açıklama:

s≠↑s←⎕ prompts for string and creates binary vector not equal to first character

b←2↓s drops first two elements of binary

(+\0=8|⍳⍴b)⊂ splits binary into groups of 8

2⊥¨ converts each group to decimal

⎕av[...] displays decoded characters

Quad-AV'nin APL + WIN için ASCII ile uyumlu olduğunu varsayıyorum?
Zacharý

@ Zacharý İlk 128 karakter için Evet. Özel APL karakterleri, genişletilmiş ASCII karakter kümesindeki karakterlerin bir kısmını değiştirir.
Graham

2

Kırmızı , 110 bayt

func[s][t: 0 i: 128 foreach c next next s[if c = s/2[t: t + i]i: i / 2 if i = 0[prin to-char t t: 0 i: 128]]] 

Çevrimiçi deneyin!

Açıklama:

Basit ve basit bir çözüm, yerleşik değil.

f: func [s] [                      ; s is the argument (string)
    t: 0                           ; total - initially 0
    i: 128                         ; powers of 2, initially 0
    b: s/2                         ; b is the second charachter
    foreach c next next s [        ; for each char in the input string after the 2nd one
        if c = b [t: t + i]        ; if it's equal to b than add the power of 2 to t
        i: i / 2                   ; previous power of 2
        if i = 0 [                 ; if it's 0 
            prin to-char t         ; convert t to character and print it
            t: 0                   ; set t to 0
            i: 128                 ; i to 128
        ]
    ]
] 

2

Google Sayfaları, 123 bayt

=ArrayFormula(Join("",IfError(Char(Bin2Dec(Substitute(Substitute(Mid(A1,3+8*(Row(A:A)-1),8),Left(A1),0),Mid(A1,2,1),1))),""

Giriş hücrede A1. Google otomatik olarak )))formülün sonuna ekler .

Açıklama:

  • Mid(A1,3+8*(Row(A:A)-1),8) üçüncü seferden başlayarak bir seferde 8 karakter parçasını kapar.
  • Substitute(Mid(~),Left(A1),0) ilk karakterin her bir örneğini 0 ile değiştirir.
  • Substitute(Substitute(~),Mid(A1,2,1),1) ikinci karakteri 1 ile değiştirir.
  • Char(Bin2Dec(Substitute(~))) öbeği ondalık ve daha sonra da ASCII'ye dönüştürür.
  • IfError(Char(~,""))bizden çok daha fazla değer Row(A:A)döndürmemizden kaynaklanan tüm hataları düzeltir, böylece bize çok fazla sıfır değeri verir ve hataları sıfır olarak verir.Bin2DecChar
  • ArrayFormula(Join("",IfError(~)))tüm Charsonuçları bir araya ArrayFormulagetirir ve Row(A:A)geri dönüşü yalnızca ilk değer yerine bir değerler dizisi yapan şeydir .




2

Python 2,8 bayt

i=input()
f=''.join('10'[x==i[0]]for x in i[2:])
while f:print chr(int(f[:8],2));f=f[8:]

Çevrimiçi deneyin!

En kısa değil - sadece alternatif bir yol.

Aşağıdaki sürüm, 98 satır bayt için çıktıyı bir satırda basar, ancak kurallar izleyen boşluklara izin verildiğini belirtir.

i=input();f=''.join('10'[x==i[0]]for x in i[2:]);o=""
while f:o+=chr(int(f[:8],2));f=f[8:]
print o

Çevrimiçi deneyin!


Son çıktı üç değil, tek satırda olmalıdır.
idrougge

OP'den: "Çıktıda liderlik ve iz bırakma boşluklarına izin verilir (/ \ s * / ile eşleşen her şey"). Newline eşleşir /\s*/.
ElPedro

1
Üzgünüm, regex notasyonunda yeterince bilgili değilim. : /
idrougge

Ne de ben değilim ama ben sadece emin olmak için Googled ;-)
ElPedro




1

Haskell , 124 105 93 bayt

f(x:_:y)=fromEnum.(/=x)<$>y
g[]=[]
g s=(toEnum.sum.zipWith((*).(2^))[7,6..0])s:g(drop 8s)
g.f

Çevrimiçi deneyin!

fher karakteri ilki ile karşılaştırarak dizgiyi bit listesine dönüştürür, Bools'yi sıfırlara ve olanlar ile çevirir fromEnum. g8 grupları, ondalık dönüştürür Bu listeyi böler ve bir şekilde elde edilen sayının değerini alır Enum, Charbir örneğidir.

değişiklikler:

  • @Laikoni sayesinde -19 bayt (içe aktarma işleminin kaldırılması, mapişleve gömülmesi )
  • @ Lynn'in cevabından ilham alan 12 bayt (daha takekısa listeyle sıkıştırılarak kurtulmak )

2
İçe aktarma toEnumyerine kullanabilir chrve bırakabilirsiniz. Ayrıca mapiçine dahil edilebilir g. Aradaki boşluk 8 skaldırılabilir.
Laikoni

1

İleri (gforth) , 83 bayt

: f over c@ 0 rot 2 do 2* over i 4 pick + c@ <> - i 8 mod 1 = if emit 0 then loop ;

Çevrimiçi deneyin!

Giriş standart bir Dördüncü dizedir (adres ve uzunluk) çıktı stdout'a yazdırılır

açıklama

over c@          \ get the value of the first character in the string
0 rot            \ add a starting "byte" value of 0 and put the length on top of the stack
2 do             \ start a loop from 2 to length-1
   2*            \ multiply the current byte value by 2 (shift "bits" left one)
   over          \ copy the reference char to the top of the stack
   i 4 pick +    \ add the index and the starting address to get address of the current char
   c@ <>         \ get the char at the address and check if not equal to the reference char
   -             \ subtract the value from our bit count, -1 is default "true" value in forth
   i 8 mod 1 =   \ check if we are at the last bit in a byte
   if            \ if we are
      emit 0     \ print the character and start our new byte at 0
   then          \ and end the if statement
loop             \ end the loop
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.