Mari kita lakukan beberapa "deciph4r4ng"


58

Dalam tantangan ini, tugas Anda adalah menguraikan string. Untungnya, algoritma ini cukup sederhana: membaca dari kiri ke kanan, setiap digit yang dijumpai N (0 hingga 9) harus diganti dengan karakter yang merupakan posisi N +1 sebelum itu.

Contoh

String input "Prog2am0in6"akan diterjemahkan dengan cara ini:

contoh

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

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 yang diuraikan asli dijamin tidak mengandung digit apa pun.
  • Setelah karakter diterjemahkan, karakter tersebut dapat direferensikan oleh digit berikutnya. Misalnya, "alp2c1"harus diterjemahkan sebagai "alpaca".
  • 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 : a000
Output: aaaa

Input : ban111
Output: banana

Input : Hel0o W2r5d!
Output: Hello World!

Input : this 222a19e52
Output: this is a test

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

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

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

Bisakah kita menerima input sebagai array string karakter tunggal? Bisakah kita berasumsi bahwa jumlahnya tidak akan lebih dari 9?
fəˈnɛtɪk

@ fəˈnɛtɪk Mengenai format input: Saya akan mengatakan tidak, kecuali ini adalah satu-satunya format yang dapat diterima untuk bahasa Anda. Kita berurusan dengan satu digit daripada angka. Jadi ya: dijamin menjadi <= 9 tetapi Anda mungkin menemukan beberapa digit berturut-turut.
Arnauld

Apakah 1bbabinput yang valid (dengan output yang diharapkan abbab)? Dengan kata lain, dapatkah rujukan membungkus tali?
Luke

@ Lukas Poin yang bagus. Tidak, 1bbabtidak valid. Saya telah menambahkan klarifikasi tentang itu.
Arnauld

Jawaban:


11

Jelly , 9 7 byte

~ịṭṭµ@/

Cobalah online!

Bagaimana itu bekerja

~ịṭṭµ@/  Main link. Argument: s

    µ    Combine the four links to the left into a chain (arity unknown).
     @   Swap the chains arguments. This makes it dyadic.
      /  Reduce s by the chain with swapped arguments. It will be called with
         right argument r (the result of the previous call, initially the first 
         character) and left argument c (the next character of s).
~            Bitwise NOT of c. This maps a digit 'd' to ~d = -(d+1), but all 
             non-digit characters 'D' to 0.
  ṭ          Tack; append c to r.
 ị           Index; select the character of the result to the right at the
             index from the result to the left. Indexing is 1-based and modular,
             so 0 is the last character, -1 the second to last, etc.
   ṭ         Tack; append the resulting character to r.    

13

Java 7, 81 80 byte

void a(char[]a){for(int i=0;++i<a.length;)if(a[i]>47&a[i]<58)a[i]=a[i-a[i]+47];}

Cobalah online!

Disimpan 1 byte berkat Anders Tornblad . Karakter pertama tidak boleh berupa angka sehingga tidak perlu diperiksa artinya kita dapat melakukan pra-penambahan sebelum memeriksa kondisi terminasi kita.


2
Karena char pertama tidak pernah mengandung digit, Anda tidak perlu memeriksanya. Karenanya, loop Anda bisa for(int i=0;++i<a.length;){saja, menghemat satu char.
Anders Tornblad

12

Haskell, 55 byte

o#c|c>'/',c<':'=o!!read[c]:o|1<2=c:o
reverse.foldl(#)[]

Contoh penggunaan: reverse.foldl(#)[] $ "Prog2am0in6 Puz0les7&1Cod74G4lf"-> "Programming Puzzles & Code Golf". Cobalah online!

Kurangi string menjadi salinan terbalik dengan nomor yang diganti oleh karakter yang sesuai. "terbalik", karena dengan cara ini kami memiliki akses yang mudah ke string sejauh ini saat mengindeks angka. Balikkan lagi.


1
Wow, saya telah menulis solusi yang tepat ini tetapi saya lambat dalam mempostingnya :) Yah, setidaknya sekarang saya tahu itu solusi yang bagus, +1
Leo

11

C, 46 byte

f(char*s){for(;*s++;)*s=s[(*s-52)/6?0:47-*s];}

Cobalah online!


C,  52   49  48 byte

Berkat @ l4m2 untuk menghemat satu byte!

f(char*s){for(;*s++;)*s>47&*s<58?*s=s[47-*s]:0;}

Mengedit string input secara langsung.

Cobalah online!

Alternatif versi 50-byte:

f(char*s){for(;*s++;)*s=abs(*s-57)>9?*s:s[47-*s];}

Versi rekursif, 48 byte:

f(char*s){*s>47&*s<58?*s=s[47-*s]:0;*s++&&f(s);}

9

05AB1E , 11 byte

vydiÂyèëy}J

Cobalah online!

Penjelasan

v            # for each character y in input
 ydi         # if y is a digit
    Â        #    push a reversed copy of the string we've built up so far
     yè      #    push the character at index y in the reversed string
       ë     # else
        y    #    push y
         }   # end if
          J  # join stack to a single string
             # output top of the stack at the end of the loop

Saya benar-benar perlu memeriksa untuk melihat apakah Anda sudah menjawab lebih sering sebelum memulai.
Guci Gurita Ajaib

@carusocomputing: Anda masih bisa memikirkan beberapa trik yang lebih baik daripada yang saya gunakan;)
Emigna

7

JavaScript (ES6), 59 53 byte

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

Disimpan 7 byte berkat fəˈnɛtɪk.

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


.charAt (...) dapat diganti dengan [...] untuk penghematan 7 byte
fəˈnɛtɪk

x.charAt (...) setara dengan x [...]
fəˈnɛtɪk

@ fəˈnɛtɪk Yap, saya pikir saya sudah mencobanya sebelumnya tetapi ternyata ada kesalahan. Terima kasih!
Tom

1
o-m-1dapat diganti dengan o+~m.
Neil

2
Karena f disebut rekursif, jumlah karakter program harus menyertakan f=bagian, jadi ini adalah 54 byte, bukan 52.
user5090812

5

Retina , 37 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

\d
$*«»
r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

Cobalah online!

Penjelasan

\d
$*«»

Ganti setiap digit d dengan d « s, diikuti oleh satu ». Kita membutuhkan yang terakhir a) untuk dapat mengenali posisi di mana d = 0 dan b) sebagai pemisah antara digit yang berdekatan.

r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

Berulang kali ( +) cocokkan dengan regex pada baris pertama dari kanan ke kiri (r ) dan kemudian ganti pertandingan paling kiri ( 1) dengan substitusi pada baris kedua.

Regex itu sendiri cocok dengan salah satu digit kami yang sekarang belum diketahui dan menghitung jumlah «s dalam grup 2. Tampilan di belakang kemudian cocok dengan karakter d(?<-2>.)* sebelum menangkap karakter yang dirujuk ke dalam grup 1. String «s dan »kemudian diganti dengan karakter yang diambil .


5

MATL , 21 19 17 16 byte

"@t4Y2m?UQ$y]]&h

Cobalah di MATL Online!

Penjelasan

        % Implicitly grab input as a string
"       % For each character in the input
  @     % Push that character to the stack
  t     % Make a copy of it
  4Y2   % Push the pre-defined array '0123456789' to the stack
  m     % Check if the current character is part of this array (a digit)
  ?     % If it is
    UQ  % Convert it to a number and add 1 (N)
    $y  % Make a copy of the element N-deep in the stack. MATL uses one-based indexing
        % So 1$y is the element at the top of the stack, 2$y is the next one down, etc.
  ]     % End of if statement
        % Non-digit characters remain on the stack as-is
]       % End of for loop
&h      % Horizontally concatenate the entire stack to form a string
        % Implicitly display the result

Penggunaan yang bagus $ydi versi baru!
Luis Mendo

@LuisMendo Terima kasih! Ya, bahasa berbasis tumpukan sangat cocok untuk tantangan ini
Suever

@LuisMendo Sayangnya ini bisa dipersingkat bahkan lebih jika Uhanya bekerja untuk digit. Sayangnya 'e'Uhasil exp(1)jika tidak saya bisa menyingkirkan 4Y2barang
Suever

Lain dari hal-hal Oktaf ...
Luis Mendo

4

JavaScript (ES6), 51 byte

f=
s=>s.replace(/\d/g,(c,i)=>a[i]=a[i+=~c]||s[i],a=[])
<input oninput=o.textContent=f(this.value)><pre id=o>

a digunakan untuk menyimpan digit yang diganti untuk menangani digit yang mengacu pada digit lainnya.


`` `s => s.replace (a = / \ d / g, (c, i) => a [i] = a [i + = ~ c] || s [i])` ``
l4m2

3

Perl 5 , 34 byte

33 byte kode + -pbendera.

s/\d/substr$_,-$&-1+pos,1/e&&redo

Cobalah online!

s/\d/.../eganti digit pertama dengan ...dievaluasi sebagai kode Perl. (dengan ...berada substr$_,-$&-1+pos,1dalam kasus itu. substr$_,-$&-1+pos,1mengembalikan substring dari $_panjang 1pada indeks -$&-1+pos, di mana $&nomor hanya cocok, dan posmerupakan indeks dari awal pertandingan. Kita hanya perlu redojika penggantian berhasil untuk mengganti setiap digit. (dan hasilnya dicetak secara implisit karena-p bendera).


Pendekatan lama, 47 byte:

44 byte kode + -Fbendera.

map{$F[$i]=$F[$i-$_-1]if/\d/;++$i}@F;print@F

Cobalah online!

Sebenarnya cukup lurus ke depan. -Fflag membagi input pada setiap karakter menjadi @F. map{...}@Fiterasi melalui @F(mis. setiap karakter input). Jika karakter jika digit ( /\d/), maka kami menggantinya dengan karakter di indeks $i-$_-1. Ini $iadalah variabel indeks saat ini (yang kami pertahankan dengan menambah setiap karakter yang terlihat).


3

JavaScript ES6, 61 59 byte

Terima kasih @ Lukas telah bermain golf 8 byte

x=>[...x].map((p,i,a)=>a[i]=/\d/.test(p)?a[i-1-p]:p).join``

Cobalah online!


x.split``bisa juga [...x], [0-9]bisa \d, bersama-sama menghemat 6B
Luke

Saat ini memiliki kesalahan di suatu tempat sehingga akan memperbaikinya terlebih dahulu
fəˈnɛtɪk

x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``untuk 46 byte
Luke

Gagal untuk spasi + "" memberikan 0 yang menyebabkannya mengambil karakter sebelumnya
fəˈnɛtɪk

x=>[...x].map((p,i,a)=>a[i]=1+p>9?a[i-1-p]:p).join``
14m2

3

05AB1E , 27 17 byte

vyDdiU)DRXèU`X}}J

Cobalah online!

vy             }  # For each character
  Dd              #   Push is_number
    i         }   #   If it is
     U            #     Save save it
      )DR         #     Wrap the (reversed) stack into an array
         Xè       #     Get the character at the saved index
           U`X    #     Flatten the whole stack
                J # Join 

2

CJam, 13 byte

q{_A,s#)$\;}/

Demo online.

Solusi ini menggunakan built-in "copy n -th item pada stack" operator CJam $untuk mengimplementasikan decoding. Dimulai dengan membaca input (dengan q) dan kemudian mengulangi karakter dari string input dan membuangnya ke stack (with {}/). Namun, di dalam loop body itu juga menduplikasi masing-masing karakter setelah diletakkan di stack (with _) dan memeriksa apakah itu digit dengan melihat posisinya dengan #di dalam string "0123456789", mudah direpresentasikan sebagai A,s.

Hasil pencarian ini adalah nilai numerik digit atau, jika karakter bukan digit, -1. The )Operator kemudian menambahkan nilai dengan satu, dan $menggantikannya dengan saat ini karakter di banyak posisi di bawah bagian atas tumpukan. Akhirnya, \;cukup hapus salinan karakter input saat ini yang kami buat _dari tumpukan, karena tidak lagi diperlukan.


2

Befunge-98 , 45 43 byte

::::#@~\1p:1g::'9`!\'/`*j;'/--1g\1p\1g#;,1+

Cobalah online!

Ide:

  1. Untuk setiap karakter dalam string input,
    1. Tulis ke baris 2
    2. Jika bukan angka, output saja
    3. Jika tidak, cari nilai yang benar, tulis ulang, lalu keluarkan
::::            ; There's a counter on the stack, duplicate it 4 times  ;
    #@~         ; Get the next char of input, exiting if there is none  ;
       \1p      ; At the location (counter, 1), write the input char    ;
          :1g   ; Re-obtain the char. Stack is now [counter * 4, input] ;

::                ; Stack: [counter * 4, input * 3]      ;
  '9`!\'/`*       ; If !(input > '9') and (input > '/')  ;
                  ; IE If ('0' <= input && input <= '9') ;
           j;...; ; Then execute the ...                 ;

; Stack: [counter * 4, input] ;
; The ... branch:             ;

'/-             ; input -> int. (input -= '/')             ;
   -            ; counter - int(input) - 1                 ;
                ; Stack: [counter * 3, lookupPosition ]    ;
    1g          ; Get the char that we want to find        ;
      \1p\1g#   ; Overwrite the current char (not the old) ;

; Both branches: ;
,1+             ; Print the number and increment the counter ;

Saya tidak bisa mendapatkan versi ini lebih pendek, tetapi yang ini adalah 44 byte:

s #@~\3p:3g::'9`!\'/`*j;'/--3g#;:10g3p,1+:::

Kupikir aku akan membaginya karena trik rapi dengan s- tetapi menyimpan counter di tumpukan mengarah ke perbaikan 1 char



2

Python 2, 75 71 byte

s='';j=-1
for i in input():s+=s[j-int(i)]if'/'<i<':'else i;j+=1
print s

Cobalah secara Online!

Sunting: Diperbaiki untuk nilai ascii antara 32-47 ; Diperbaiki untuk decoding ganda (mis. "Alp2c1" ke "alpaca")


1
@Arnauld Tidak. Maaf, saya tidak cukup membaca spec. Saya akan segera memodifikasi
pecandu matematika

Sepertinya ada bug. untuk 'Prog2am0in6 Puz0les7&1Cod74G4lf'cetakan program Anda Programming Puzzles &7Code1Golf! Saya mencoba dengan kedua tautan TIO yang dibagikan!
Keerthana Prabhakaran

@KeerthanaPrabhakaran Terima kasih! Diperbaiki dengan biaya 0 byte! (Solusi alternatif saya tidak membuat jalan pintas)
pecandu matematika

Itu pendekatan yang bagus!
Keerthana Prabhakaran

Bisakah Anda jelaskan '/' <i <':'. Saya tahu ini sedang menguji apakah itu angka tetapi bagaimana cara kerjanya?
Matias K

2

PHP 7.1 67 59 byte

while(_&$c=$argn[$i++])$t.=($c^"0")<"
"?$t[~+$c]:$c;echo$t;

Mengambil input dari STDIN; jalankan sebagai pipa dengan -nRatau coba online .

  • _&$c=$s[$i++]loop through string ( _&$cakan menghasilkan sesuatu yang tidak"0" ; jadi satu-satunya karakter yang dapat memecah loop adalah string kosong = akhir input)
  • $c^"0" matikan bit 5 dan 6 dalam kode ascii
  • <"\n" periksa apakah hasilnya <chr (10)
  • jika demikian, itu adalah digit: cetak karakter sebelumnya dengan indeks (dan salin ke indeks saat ini)
  • lain cetak karakter ini

Terima kasih @Christoph untuk menghemat 12%


1
Saya tahu ini adalah jawaban lama tetapi: Offset string negatif! (dan itu $s=$argn...?)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
Christoph

2

Vim makro / penekanan tombol, 49 byte

^M mewakili karakter kembali (0x0A, 1 byte).

qqqqq/[0-9]^Myl:exe 'norm '.(@"+1).'h'^Mylnphx@qq@q

Penjelasan

qqq                                                     clear register q
   qq                                                   record into q
     /[0-9]^M                                           move the cursor to the next digit
             yl                                         yank the digit
               :exe 'norm '.(@"+1).'h'^M                move the cursor left that number of characters plus one
                                        yl              yank the char
                                          n             go back to the digit
                                           p            paste the char 
                                            hx          delete the digit
                                              @q        recursive call
                                                q       stop recording
                                                 @q     run the macro

2

APL (Dyalog Classic) , 25 23 byte

-2 byte terima kasih kepada @FrownyFrog

((⊂⌷⊢)⍣≡⍳∘≢-11|⎕d∘⍳)⊃¨⊂

Cobalah online!

menggunakan ⎕io←1

(di bawah ini merupakan nilai tengah dalam evaluasi)

⎕d adalah string '0123456789'

⎕d⍳⍵menemukan (1 - berdasarkan dalam hal ini) indeks karakter di ⎕d; untuk non-digit indeksnya adalah 11

11|⍵ adalah modulo - 11s menjadi 0s

≢⍵ adalah panjangnya

⍳≢⍵adalah 1 2 ...sampai≢⍵

jadi, (⍳≢⍵)-11|⎕d⍳⍵beri kami vektor i dari indeks di mana kita harus mencari untuk mendapatkan karakter yang dihasilkan; namun beberapa indeks tersebut mungkin mengarahkan ke indeks lain (lebih kecil). Untuk menghitung penutupan transitif (yaitu indeks efektif), kami mengindeks vektor ke dalam dirinya sendiri ( ⊂⌷⊢, kereta setara dengan (⊂i)⌷iatau i[i]) dan ulangi sampai stabil ( ⍣≡dikenal sebagai operator titik tetap ).

akhirnya kami mengindeks ke string asli: (...)⊃¨⊂


Bagaimana itu terlihat seperti kereta api?
FrownyFrog

@FrownyFrog memang, lebih pendek
ngn


1

Japt , 24 byte

£Xn >J?U=UhYUgJ+Y-X):PÃU

Cobalah online!

Penjelasan:

£Xn >J?U=UhYUgJ+Y-X):PÃU
£                     Ã    Iterate through the input (implicit U) 
                             X becomes the iterative item, Y becomes the index
 Xn                          Try parseInt(X)
    >J                       > -1
                               In this case, this checks if X is a digit
      ?                      If true:
       U=                      Set U to 
         UhY                     U with the char at index Y set to:     
            UgJ+Y-X               The index at -1+Y-X
                   ):        Else:
                     P         variable P (just a no-op in this case)
                       U   Finally, return U


1

Python 2 , 58 byte

lambda s:reduce(lambda t,c:t+(c+t)['/'<c<':'and~int(c)],s)

Ini pada dasarnya adalah port jawaban Jelly saya, ditambah digit cek dari @ xnor's Python answer.

Cobalah online!



1

JavaScript ES6, 54 byte

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


1
Selamat datang di PPCG! Jika Anda tidak memerlukan nama fungsi untuk panggilan rekursif, fungsi yang tidak disebutkan namanya valid, sehingga Anda dapat menyimpan dua byte di f=.
Martin Ender

1

> <> (Ikan), 108 byte (= 9 x 12 kotak)

01-r>:0(\
"/"&::;?/
)?\v    \
":/v!?(":
")\ :>:"0
 !?\
${/  \ -1
&>\ ~{:&$
\ \ :"0"=
/\- 1}$/?
:v&//}~/~
 \o}\&$/ 

Coba di sini untuk melihat ikan berenang di sekitar.

  • Tambahkan -1 ke tumpukan input lalu balikkan tumpukan.
  • Loop: Jika nilai teratas adalah -1 lalu akhiri (kami telah bersepeda melalui semua karakter). Jika tidak:
  • Masukkan karakter teratas dalam register; periksa untuk melihat apakah kisarannya "0" hingga "9". Jika begitu:
    • putar tumpukan jumlah tempat yang tepat
    • dapatkan karakter yang ditunjukkan
    • putar kembali dan ganti nomor dengan karakter dari register
  • Keluaran; melanjutkan loop.

1

8086 kode mesin, 35 byte

00000000  be 82 00 ac 98 50 2c 30  3c 09 77 0c 4e 89 f7 4e  |.....P,0<.w.N..N|
00000010  29 c6 58 ac aa 89 fe 50  5a b4 02 cd 21 80 fa 0d  |).X....PZ...!...|
00000020  75 e1 c3                                          |u..|
00000023


1

Japt v2.0a0, 16 byte

r\d@=hYUgY-°X¹gY

Cobalah


Penjelasan

                     :Implicit input of string U
r                    :Replace
 \d                  :  RegEx /\d/g
   @                 :  Pass each match X at index Y through a function
     hY              :    Set the character at index Y in U
       UgY-°X        :    To the character at index Y-++X
    =        ¹       :    Reassign to U
              gY     :    Get the character at index Y

1

J , 20 byte

{~[:{~^:_#\-2+_1".,.

Cobalah online

                  ,.  Each character on a separate row
              _1".    Convert to numbers, replacing non-numbers with -1
                         (it becomes one row again)
            2+        Add 2.
         #\           Prefix lengths (range 1..length)
           -          Subtract
  [:{~^:_             Index into itself as long as it changes the result
{~                    Index into the original string

Penghargaan untuk ngn untuk inspirasi.

22 byte

(],,{~1{._1-_1".[)/@|.

Ini adalah port jawaban Jelly.

                    |. The string backwards, because reduce is right-to-left.
            _1".[      The next character as a number (d), -1 if it's not a number,
                          and a space character produces an empty array.
         _1-           -1-d
      1{.              Take 1. If we have a nothing
                          at this point, that makes it a 0.
   ,                   Prepend the next character to the result of the previous call.
    {~                 Select the character. 0 is the first, _2 is second to last.
 ],                    Append the result.

Dalam kedua solusi, versi yang menggunakan TIO menginterpretasikan tunggal .sebagai angka 0, sehingga tes terakhir gagal. Versi yang lebih lama (≤7) tampaknya berfungsi dengan benar.

Cobalah online!

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.