Mari kita lakukan beberapa "enciph5r47g"


35

Ini kebalikan dari Let's do some "deciph4r4ng"


Dalam tantangan ini, tugas Anda adalah menyandikan string. Untungnya, algoritme ini cukup sederhana: membaca dari kiri ke kanan, setiap karakter penulisan khas (rentang ASCII 32-126) harus diganti dengan angka N (0-9) untuk menunjukkan bahwa itu sama dengan karakter N + 1 posisi sebelumnya. Pengecualian adalah ketika karakter tidak muncul dalam 10 posisi sebelumnya di string asli. Dalam hal ini, Anda cukup mencetak karakter lagi. Secara efektif, Anda harus dapat membalikkan operasi dari tantangan asli.

Contoh

String input "Programming"akan dikodekan dengan cara ini:

Contoh 1

Oleh karena itu, output yang diharapkan adalah "Prog2am0in6".

Klarifikasi dan aturan

  • String input akan berisi karakter ASCII dalam kisaran 32 - 126 secara eksklusif. Anda dapat berasumsi bahwa itu tidak akan pernah kosong.
  • String asli dijamin tidak mengandung digit apa pun.
  • Setelah karakter dikodekan, karakter tersebut dapat direferensikan oleh digit berikutnya. Misalnya, "alpaca"harus dikodekan sebagai "alp2c1".
  • Referensi tidak akan pernah membungkus string: hanya karakter sebelumnya yang dapat direferensikan.
  • Anda dapat menulis program lengkap atau fungsi, yang mencetak atau menampilkan hasilnya.
  • Ini adalah kode golf, jadi jawaban tersingkat dalam byte menang.
  • Celah standar dilarang.

Uji kasus

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.

6
Saya melihat bahwa test case Anda selalu menggunakan digit serendah mungkin untuk setiap penggantian. Apakah ini perilaku yang diperlukan, atau bisakah kita menggunakan angka yang lebih tinggi juga, ketika ada lebih dari satu kemungkinan?
Leo

@ Leo Anda dapat menggunakan satu digit yang Anda inginkan 0-9 selama itu valid.
Engineer Toast

Ini seperti encoder pindah-ke-depan , kecuali tanpa memindahkan :)
pipe

Jawaban:


6

05AB1E , 20 19 18 byte

-2 Terima kasih kepada Emigna

õ¹vDyåiDykëy}?yìT£

Cobalah online!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

Saya pikir itu juga )¹vDyåiDykëy}?y¸ìT£berfungsi.
Emigna

Sebenarnya, menggabungkan jawaban Anda dengan jawaban saya õIvDyåiDykëy}?yìT£untuk 18 :)
Emigna

@Emigna Merasa bebas untuk memperbarui milik Anda dengan itu :)
Riley

Saya tidak akan memikirkannya jika bukan karena jawaban Anda, jadi Anda harus memilikinya. Kerja bagus!
Emigna

@ Emigna kurasa itu adil. Terima kasih!
Riley

12

Retina , 24 23 byte

(.)(?<=\1(.{0,9}).)
$.2

Cobalah online!

Substitusi regex yang cukup sederhana. Kami mencocokkan setiap karakter dan mencoba menemukan salinannya 0-9 karakter sebelum itu. Jika kami menemukannya, kami mengganti karakter dengan jumlah karakter yang kami harus cocok untuk mendapatkan salinan.

Hasilnya tidak cukup cocok dengan kasus uji, karena yang ini menggunakan digit terbesar yang mungkin bukan yang terkecil.


4
Variable length look-behind curang: p
Dada

8
@Dada Variable-length lookbehind adalah cara pencerahan.
Martin Ender

Sayangnya itu ... Jika Anda bosan, silakan menerapkannya di dalam Perl!
Dada

Sesuai komentar OP tentang tugas asli, "Anda dapat menggunakan satu digit yang Anda inginkan 0-9 selama itu valid." ... jadi kemungkinan terbesar harus valid
Doktor J

@DoktorJ ya, saya mengubahnya setelah OP menambahkan klarifikasi itu.
Martin Ender

8

JavaScript (ES6), 74 57 54 byte

Disimpan 3 byte berkat ETHproduksi dengan yang brilian, p=/./gbukan p={}(terinspirasi oleh Neil)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

Uji kasus


Karena string dijamin tidak mengandung digit, dapatkah Anda menggunakan sbukan p?
Neil

(Saya dapat mengalahkan findversi asli Anda dengan menggunakan lastIndexOf, yang sedikit mengejutkan mengingat bahwa panjangnya 11 huruf ....)
Neil

@Neil Saya tidak di depan komputer sekarang tapi saya tidak berpikir itu akan berhasil karena string JS tidak dapat diubah.
Arnauld

2
Saya dapat mengonfirmasi bahwa menyetel properti pada string literal tidak berfungsi. Tapi ... sepertinya itu berfungsi dengan regex, jadi saya pikir Anda mungkin bisa lakukan s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)untuk menghemat 3 byte.
ETHproduksi

1
@ YOU Saya tidak benar-benar tahu apa yang terjadi di sini, tetapi ternyata saya memperkenalkan bug untuk semua browser pada edit terakhir saya. Ini sekarang sudah diperbaiki. Terima kasih telah memperhatikan!
Arnauld

7

Haskell , 72 66 byte

Terima kasih kepada Laikoni untuk bermain golf 6 byte!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

Cobalah online!

Fungsi ini %membuat string yang diproses sebagian terbalik dalam argumen kedua, sehingga dapat mencari 10 elemen pertama dari string ini untuk mencari kejadian dari karakter yang diperiksa. Pengajuan terdiri dari fungsi (%"")yang tidak disebutkan namanya yang memanggil fungsi sebelumnya dengan string kosong sebagai argumen kedua.


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])menghemat dua byte.
Laikoni

Tunggu, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]simpan lebih banyak lagi.
Laikoni

Membalik saat bepergian alih-alih menggunakan reversemenyimpan satu byte lebih lanjut: Cobalah online!
Laikoni

@Laikoni Terima kasih, itu luar biasa!
Leo


3

Perl 5 , 36 byte

35 byte kode + -pbendera.

s/(\D)(.{0,9})\K\1/length$2/e&&redo

Cobalah online!

Beberapa penjelasan:
Tujuannya adalah untuk mengganti karakter non-digit ( \Dtetapi itu sesuai dengan referensi-ulang \1di regex saya) yang didahului oleh kurang dari 10 karakter ( .{0,9}) dan karakter yang sama ( (\D)... \1) pada panjang .{0,9}grup ( length$2). Dan redosementara karakter diganti.


tampaknya .*tidak diperlukan, karakter apa pun yang valid dalam kisaran sebelum digit yang diganti ok.
colsw

@ConnorLSW Yup, saya baru saja melihat pembaruan dari tantangan itu dan mengubah jawaban saya, terima kasih telah menunjukkannya.
Dada

3

Python 2, 89 84 byte

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

Cobalah secara Online!

Iterasikan melalui string secara terbalik, dan buat string baru dengan angka yang benar dimasukkan.


3

Japt , 18 byte

£¯Y w bX s r"..+"X

Cobalah online!

Penjelasan

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E , 20 byte

õIv¹N£RT£©yåi®ykëy}J

Cobalah online!

Penjelasan

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string

2

Python 3, 125 118 byte

def p(x):print(x,end='')
l={}
for i,c in enumerate(input()):
 if l.get(c,i+9)<i+9:
  p(i-l[c]-1)
 else:
  p(c)
 l[c]=i

Cobalah online!


2

C (tcc) , 113 byte

Karena fungsi membuat salinan string input, ukuran input maksimum adalah 98 karakter (lebih dari cukup untuk memenuhi input uji terpanjang). Tentu saja, ini dapat diubah ke nilai lainnya.

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

Cobalah online!

Edit

-15 byte. Terima kasih Johan du Toit .


Agh! Batasi input hingga 98 karakter dan simpan satu byte!
pipa

Solusi yang bagus tetapi Anda dapat menyimpan 15 byte lagi: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit

@JohanduToit Terima kasih! Saya mempunyai satu pertanyaan. Bagaimana tepatnya s [i] berfungsi sebagai kondisi for for? Saya sudah sering melihatnya di jawaban orang lain di situs web ini.
Maxim Mikhaylov

@ Max Lawnboy. Anda awalnya memiliki yang berikut: 's [i] ^' \ 0 '' yang merupakan singkatan untuk [i]! = '\ 0' '. Huruf karakter '\ 0' sama dengan nol sehingga Anda dapat menulisnya seperti ini: 's [i]! = 0'. Pernyataan if dalam C hanya menguji jika nilai dievaluasi menjadi nol atau tidak nol sehingga '! = 0' tidak diperlukan.
Johan du Toit


2

Java 7, 102 101 byte

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

Cobalah online!

-1 byte terima kasih kepada Kevin Cruijssen . Saya selalu menikmati alasan untuk menggunakan operator masuk.


Mengapa --c>=0? Anda dapat menggantinya dengan c-->0untuk menyimpan byte.
Kevin Cruijssen

@KevinCruijssen Saya entah bagaimana memilikinya di kepala saya bahwa saya perlu melakukan pra-pemilihan kalau tidak perhitungan yang sebenarnya akan salah ... Tangkapan yang bagus!
Poke

1

MATL, 31 30 byte

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

Cobalah di MATL Online!

Penjelasan

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

Anda mungkin sedikit canggung, tetapi saya sangat tidak tahu di mana. Input this is a testmenghasilkan this 222a1te52bukan this 222a19e52. Yang kedua ttidak dikonversi menjadi 9.
Engineer Toast

@ Engineer Haha terima kasih. Aku akan melihatnya.
Suever

1

PHP, 104 Bytes

solusi ke depan

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

Solusi mundur

Versi Online

PHP, 111 Bytes

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 Bytes

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

Versi Online


1

REXX, 124 125 byte

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

Anda mungkin agak bingung. Saya tidak tahu REXX tapi saya kira kesalahan ini sejalan 7 di mana ia memiliki s<9bukan s<10atau s<=9. Input this is a testmenghasilkan this 222a1te52bukan this 222a19e52. Yang kedua ttidak dikonversi menjadi 9. Cobalah online
Engineer Toast

Terima kasih, itu adalah upaya bodoh untuk memotong satu byte. Kode telah diperbaiki.
idrougge

1

C (gcc) , 117 103 byte

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

Cobalah online!

103 byte tanpa impor string.h, berfungsi dengan peringatan. Jika ini melanggar aturan, saya akan menariknya

Kode Cantik:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

Suntingan:

  • Berubah dari LLVM ke gcc untuk memungkinkan i, j deklarasi, impor lib dihapus.
  • Menambahkan pembungkus fungsi untuk kepatuhan

Sarankan (i=strlen(s);s[--i];)alih-alih(i=strlen(s)-1;s[i];i--)
ceilingcat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.