Kodlanmış bir dizeyi genişlet


18

Klasik çalışma uzunluğu kodlama ve kod çözme var.

input   output
a3b2c5  aaabbccccc

Ve bu oldukça basit ve daha önce yapıldı.

Zorluk, çalışma uzunluğundan önce birden çok karakter ( 0-9 arasındaki tek bir basamak) olduğunda standart olmayan bir davranışı da hesaba katmaktır. Çalışma uzunluğu rakamından önceki her karakter (rakam olmayan veya dizenin sonundan önceki son rakam) bu değere ayrı ayrı uygulanır ve sırayla yazdırılır.

Bazı kenar durumları dahil bazı test giriş ve çıkışları:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Bir karakter dizisinin ( [a-zA-Z0-9]+) ardından çalışma uzunluğu uzunluğu ( [0-9]) gelmelidir
  • Yalnızca geçerli girdilerin dikkate alınması gerekir ( ([a-zA-Z0-9]+[0-9])*)
    • evet, boş dize geçerli girdi.
  • Giriş standart giriş üzerinden, çıkış standart çıkış üzerinden

Bu kod golf, bayt sayısını kazanan belirler.


@AlexA. Doğru. Zaman zaman görmekten hoşlandığım bayt sayısı tarafından cezalandırılan bazı esolangs var. (Bunun neden bu şekilde saymak için bir hata olabileceğine dair önerilere kesinlikle açığım)

4
@MichaelT Karakterlere göre puanlama, kaynak kodun UTF32'ye sıkıştırılmasını kuvvetle teşvik eder, bu da karakter başına 4 bayta kadar kodlamaya izin verir, ancak tamamen okunamaz.
isaacg

@isaacg fair 'nuff. Bayt olarak değiştirmek için düzenleyeceğim. Sclipting'in stilini gelecekteki zorluklar için kabul edilebilir olarak ifade etmenin bir yolunu aydınlatacağım.

Girdi boş dize ise gönderimimizin hatasız tamamlanması gerekiyor mu? Meta üzerinde konsensüs standart hataya o çıktı göz ardı edilebilir, ancak açıkça belirtildiği beri ben sormak gerekir.
Dennis

@ Boş bir dize girdi olması gerektiği gibi durmalıdır. Sonsuz bir döngüye girmemeli veya standart çıktıya başka bir metin basmamalıdır.

Yanıtlar:


3

Pip, 22 + 1 = 23 bayt

-rBayrak kullanır . Bunun 1) girişten sonra bir EOF girmenizi (Linux'ta Ctrl-D, Windows'ta Ctrl-Z) veya 2) girişi başka bir yerden girmesini gerektirdiğini unutmayın.

(^_@<v)X_@vMa@`\D*\d+`

Açıklama:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

Harita işleminin sonucu aslında bir liste listesidir, ancak varsayılan olarak listeler yazdırıldığında birlikte birleştirilir, bu nedenle dizeye manuel dönüştürmeye gerek yoktur.

Girişli örnek a13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip, 2 gün önce temel regex desteğine sahip . Harika zamanlama!


Bu -rbayrakla çalışır (ve ustalaşır) . (Soru, girdinin STDIN'den gelmesi gerektiğini belirtir.)
Dennis

@Dennis Oops, bunu kaçırdı. Bayt sayısına bayrak eklendi. Ekstra bayraklar qyerine özel değişkeni kullanabilmeliydim a, ancak bir hata var gibi görünüyor ve iki kez giriş istiyor.
DLosc

Sonunda regex desteği ile bir golf dili!
Dennis

@Dennis şimdi pip'e kaydığını görüyorum!
Doktor,

8

Perl / Bash 54 40 + 1 = 41 bayt

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

Temel olarak bir normal ifade içindeki bir normal ifade. Ve biraz sihir.

açıklama

Dış regex, /(\D*\d*)(\d)/gher bir çalışma uzunluğu kodlanmış grubu çıkarır. Tekrarlanacak şeyleri ve tekrar $1sayısını yakalarız $2. Şimdi bu grupların her birini o grubun genişlemesi ile değiştiriyoruz. Bunun için, kodu "\$1=~s/./\$&x$2/egr" iki kez değerlendiririz ( /eedış ikame üzerindeki bayrakta olduğu gibi ).

İlk değerlendirme sadece dizeye tekrar sayısını enterpolasyon edecektir - diğer değişkenler ters eğik çizgi ile korunmaktadır. Girdi varsayıldığında, a14şimdi $1=~s/./$&x4/egrtekrar değerlendirilecek olan koda sahip olacağız.

Bu, ikamesinin $1(tekrarlanacak şeyler a1) içeriğine uygulanacaktır . İkame her karakterle eşleşir .. $&Değişken biz tekrar bütün maç, tutan x4kez. Bunu /gher maç için lobal olarak yapıyoruz /rve $1değişkeni (salt okunur) değiştirmek yerine ikame edilmiş dizeyi aşındırıyoruz . Yani iç ikamenin sonucu aaaa1111.

-pBayrak her bir giriş hattına ikame uygular ve sonuç yazar.


3
Bunu, -pdeğiştirici için sadece 1 bayt eklediğiniz bir Perl çözümü olarak puanlamak gelenekseldir . 45 bayt sayıyorum. Buna ek olarak, \Dbunun yerine de kullanabilmeniz gerekir [a-z], bu da ihtiyacı ortadan kaldırır i.
Dennis

7

CJam, 33 31 27 bayt

Ughh, düzenli ifadelerin olmaması bunu oldukça uzun hale getiriyor ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

Nasıl çalışır

Giriş dizesinin tüm karakterleri arasında dolaşırız ve her yinelemede en son karşılaşılan karakteri izleriz (boş bir karakterle ilk kez başlayarak). Ardından, geçerli karakterin sayısal olup olmadığını ve son karakterin sayısal olup olmadığını kontrol ederiz . Eğer öyleyse, önceki karakterleri (daha önce tekrarlanmamış olan) tekrarlar, sayı kez.

(Biraz eskimiş kod genişletme)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

Buradan çevrimiçi deneyin


Bayt niteleyicisinin neden olduğu sorunun gösterilmesini takdir ediyorum. Teşekkür ederim. Ben nasıl tek bir komut çok baytlık bir karakter olduğu dil bu boşluk için cezaevi aracılığıyla almak için gösterdi UTF kodlama izin vermeden cezalandırılamaz yeterlilik ifade nasıl düşünüyorum. PS Sağladığınız algoritmik dökümü görmeyi gerçekten çok seviyorum.

6

rs , 43 71 karakter

Bu çok çabuk döndü. Aptal numaralar ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

Burada deneyin!

Orijinal sürüm (giriş gibi çalışmadı 123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

açıklama

İlk satır örneğin sayıları içeren dönüm koşular arasındaki boşluk yerleştirir a313içine a3 13.

İkinci satır, sürekli gibi sıkıştırılmış kodlamalar genişler aa5için a5a5.

Üçüncü satır, a5 içine aaaaakullanılarak tekrar operatör .

Son satır boşlukları kaldırır.


Nasıl işler a123b1?
Doktor

@Optimizer İyi değil. Biraz
ince

@Optimizer Düzeltildi.
kirbyfan64sos

5

Javascript ( ES6 ), 86 83 bayt

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

Yorumlananlar:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))Aynı şeyi yapmayacak mısın ? Sadece 71 bayt uzunluğundadır.
Ismael Miguel

@IsmaelMiguel, yalnızca rakamdan önce tek bir karakter olsaydı işe yarar. Dizi anlama, her bir karakterin tek tek tekrarlanmasını sağlar.
nderscore

Deneyin Array(6).join('12')ve dönecektir '1212121212'.
Ismael Miguel

Bu çalışıyor: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(aynı 71 bayt uzunluğunda, es6fiddle.net/ia7gocwg üzerinde test edildi )
Ismael Miguel

1
3 bayt demek için farklı (açık) bir yol buldum: D
nderscore

4

CJam, 27 25 bayt

r_'A+1>.{64&1$>{])~f*o}&}

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.

3

Pyth, 33 32 28 bayt

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Çevrimiçi deneyin: Gösteri veya Test koşum takımı

açıklama

Örnek girişi kullanarak kodu açıklayacağım aa1a23b2. İnşallah bu takip etmek biraz daha kolay.

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'


2

JavaScript 112

alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))


2

Python 2.7, 98 bayt

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

Bu, sadece bir rakam gelmeyen basamaklar için basit bir normal ifade araması yapar ve ardından her grupta dize aritmetiği yapar ve hepsini tekrar birleştirir.


Python 2'den 3'e geçerek 2 bayt kaydedebilirsiniz raw_input, inputancak printparantez gerekir.
Alex A.

Doğru, ama python 2.7'de golf yapmayı tercih ediyorum.
özyinelemeli

1

Julia, 105 99 95 87 bayt

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

Bu, a girişinin bir dize döndürdüğü bir dizeyi alan adsız bir işlev oluşturur. Aramak için bir ad verin, örn.f=s->... .

Burada, biri diğerinin içine yerleştirilmiş iki dizi kavrama kullanılır. Dış kavrama, giriş dizesinin her bir eşleşmesine normal ifadeye karşı etki eder\D*\d*\d . İç kavrama, maçın her karakterini takip eden rakama göre tekrarlar. İç dizinin elemanları bir dizeye birleştirilir, bu nedenle dış dizi bir dizgi dizisidir. Bunlar birleştirilir ve iade edilir.

Julia'da karakter dizileri karakter dizileri gibi ele alınabilir. Ancak, Julia'daki Charve Stringtürlerinin tanımlanan yöntemlerle aynı olmadığını unutmayın ; özellikle ^karakterler için tekrarlama yöntemi yoktur . Bu, kıvrık bir geçici çözüm kullanır:

  • Kullanılarak kaldırılan son karakteri atlayan dizenin üzerinde döngü chop() .
  • Geçerli karakteri kullanarak bir dizeye dönüştür string() .
  • Aynı zamanda bir karakter olan izleyen basamağı bir tamsayıya dönüştürün. Ancak, örneğin,int('4') 4 döndürmez unutmayın. Aksine, bu durumda 52 olan kod döndürür. Böylece gerçek tamsayıyı geri almak için 48 çıkarabiliriz.
  • 'E string(b)göre tekrarlayın int(p[end]) - 48.

Örnekler:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"

1

Python 3, 148 144 136 135 Bayt

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

Öneriler için Pietu1998 ve mbomb007'ye teşekkürler.

Python 2, 161 151 147 139 138 Bayt

Belki bugün işte uzun bir gündü, ama hayatım boyunca bunu nasıl golf edeceğimi anlayamıyorum ..

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o

3
Python 3 olarak değiştirmek birkaç bayt ( raw_dışarı, parantez içine print) kaydeder .len(d)>0ile ikame edilmiş olabilir d, boş bir liste falsy ve boş olmayan bir listesi truthy olduğu. list(...)doğrudan gidebilir for. İçindeki köşeli parantezler w([...])gereksiz çünkü tek argüman. İçindeki alanı kaldırabilirsiniz ) for. Şimdiye kadar bulduğum küçük şeyler bunlar.
PurkkaKoodari

@ Pietu1998 Yardımınız için teşekkürler!
Kade

Yaklaşımınızı çok fazla değiştirmeden, list()dizeler yinelenebilir olduğundan kurtulabilirsiniz. Kullanabilirsiniz w=r=''. Bunu çok değiştirmek istiyorsanız, benim çözümüme bakın. :)
özyinelemeli

if c.isdigit() olabilir if'/'<c<':' yanılmıyorsam eğer,.
DLosc

@DLosc teşekkürler, işe yarıyor gibi görünüyor.
Kade

0

Java 7, 175 bayt

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

Zor göründüğünden daha zor, imo ..

Test edilmemiş ve test kodu:

Burada deneyin.

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

Çıktı:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
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.