Bir dizedeki her sayıyı artırma


11

Ondalık sayılar içeren bir dize verildiğinde:

teststring134this 123test string54 100

yeni dize vermek için bu dizedeki her sayıyı birer birer artırın

teststring135this 124test string55 101.

Dize şu şekilde sağlanabilir:

  • bir komut satırı argümanı
  • STDIN
  • sabit kodlanmış bir değişken veya işlev bağımsız değişkeni

Bir numara için tüm olası konumları kapsamak:

  • bir kelimenin öneki olarak; 123test124test
  • bir kelimenin soneki olarak; test123test124
  • bir kelimenin içinde; te123stte124st
  • yalnız test 123 testtest 124 test

İşte Python'da golf dışı bir çözüm:

NUMBERS = '0123456789'

def increment(s):
    out = ''

    number = ''
    for c in s:
        if c in NUMBERS:
            number += c
        else:
            if number != '':
                out += str(int(number) + 1)
                number = ''
            out += c

    if number != '':
        out += str(int(number) + 1)
        number = ''

    return out


print "\"%s\"" % (increment('teststring134this 123test string54 100'))

Bu bir code-golfsoru, en kısa kod kazanıyor.


5
Eğlenceli gerçek: Bu 3 saf regex ikamesi ile yapılabilir (geri arama yok) stackoverflow.com/questions/12941362/… (bu en golf yolu olmaz)
Martin Ender

4
Girdiyi belirttiniz ancak çıktı vermediniz. Giriş spesifikasyonunuzdan hem STDOUT hem de dönüş değerinin iyi olduğunu varsayıyorum. Ancak sonucu sabit kodlu bir değişkente de saklayabilir miyiz (ondan girdi alabileceğimiz gibi)?
Martin Ender

1
Taşımak ne olacak? 999'a ne olur?
kabarık


7
Negatif sayılar ne olacak? Ondalık virgüllü sayılar ne olacak? Ondalık noktaya sahip sayılar ve ondan önce hiçbir şey yok (belki eksi işareti hariç)?
Peter Taylor

Yanıtlar:


23

Perl, 14 bayt

s/\d+/$&+1/ge

-pBir bayt olarak saydığım anahtarı gerektirir .

Örnek çalışma

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

5
Cevabım buradakine çok benzer haha codegolf.stackexchange.com/a/37113/29438
hmatt1

12

Yakut, 30 24 bayt

$><<s.gsub(/\d+/,&:next)

Saklanacak girdinin beklenmesi s.


3
Could $1.nextbloğunda kullanılacak?
Ağustos

@Ağustos güzel, teşekkürler! nextO kadar sofistike olduğunu bilmiyordum .
Martin Ender

11

Vim - 13 tuş vuruşu

0qqqqq^Al@qq@q

Girişin geçerli satır olmasını bekler.

Veya 8 + tavan (log (n)) tuş vuruşlarında sonlu sayıda (ör. 999):

0qq^Alq999@q

Bu işi yapamıyorum .... (vim 7.0.237 kullanıyorum)
Jerry Jeremiah

10

JavaScript (ES6) - 28

H=k=>k.replace(/\d+/g,k=>++k)

Kullanarak çalıştırın H("test 123 234t").


1
Dışarı alabilir H=ve sadece anonim fonksiyonu var.
Mama Fun Roll

8

Perl, 23

Giriş dizesinin atandığını varsayar $_

s/\d+/@{[$&+1]}/g;print

8

Python 2-59

Dizeyi değişken olarak sağlayın n

import re;print re.sub('\d+',lambda x:`int(x.group())+1`,n)

6

C99-86 (GCC 4.9.0 ve Visual C ++ 2013)

Düzenleme: Hem GCC 4.9.0 (-std = c99 ile) hem de Visual C ++ 2013 başarıyla (uyarılarla) dahil olmadan aynı kodu oluşturmak. Bunu yapabileceğini bilmiyordum! İpucu için teşekkürler.

Düzenleme: Hatta dize oluşturmak ve daha sonra yazdırmak yerine anında ekranda yazmak gerektiğini bana olmadı. Bu büyük bir fark yaratıyor. Teşekkürler Dennis!

Bu sabit kodlanmış bir dize kullanıyor, ancak dize içeriği toplam sayılmaz (= "" sayılır).

main(i){for(char*q,*s="test123test999test-1test";i=strtol(s,&q,0),*s;q>s?printf("%d",i+1,s=q):putchar(*s++));}

Temelde her biri bir tamsayı olup olmadığını kontrol etmek için her seferinde bir karakter dizesinden geçer. Eğer öyleyse, tamsayıyı arttırır ve çıktıya yazar, aksi takdirde geçerli karakteri çıktıya kopyalar.

Bu, s kodunu arttırdığı için sabit kodlu dizeyi sızdırıyor.


1
Eminim bazı includes kurtulmak ve hala gcc ile iyi derlemek olacaktır.
Martin Ender

1
Bu, örn. İçeren bir dize ile çalışır 99mı?
anatolyg

@ MartinBüttner: Evet ama o zaman geçerli C olmazdı, sadece gcc üzerinde çalışan bir şey.
R .. GitHub BUZA YARDIMCI DURDUR

@R .. Buna genellikle PPCG'de izin verilir. Ben kimse şikayet etmeden oldukça sık gördüm (ve daha sonra yaptım).
Martin Ender

Evet, bu benim genel bir huyum. Geçerli C. aslında değilse dil :-) yerine C den, "[. Kesmek üzerinde çalışmaya başına vb özellikle kemer /] üzerinde C" "GCC" ya da listelenmiş veya benzeri olmalıdır
R .. GitHub DUR BUZA YARDIM

5

J (20)

Girdinin değişkende saklanmasını bekler a.

'\d+'>:&.".rxapply a

Ölçek:

   a=:'teststring134this 123test string54 100'
   '\d+'>:&.".rxapply a
teststring135this 124test string55 101

5

(f?) lex (39)

Dosya inc.l:

%%
[0-9]+ printf("%d",atoi(yytext)+1);

Derleme:

$ flex inc.l
$ gcc lex.yy.c -o inc -lfl

Çalıştırmak:

$ echo 'teststring134this 123test string54 100' | ./inc
teststring135this 124test string55 101

$ i='(-: 2 empty bottles of beer :-)'
$ tty=$(tty)
$ for n in {2..5} ; do i=$(./inc<<<$i|tee $tty) ; done
(-: 3 empty bottles of beer :-)
(-: 4 empty bottles of beer :-)
(-: 5 empty bottles of beer :-)
(-: 6 empty bottles of beer :-)

Bunu orijinal ile test etmedim lex. Yorumlarınızı bekliyoruz.


1
Bu %%kullanıcı kodu olmadığından sondaki işareti bırakabilirsiniz
Josh

Hey ... evet! Denedim ama sondaki satırsonu olmadan ve bu başarısız oldu ... o zaman son satırsonu eklemeye çalışmadım ... ;-) ... aptalca bir hata!

3

Emacs - 20 karakter

C-M-% [0-9]+ RET \,(1+ \#0) RET !

İşlenecek metnin geçerli arabellekte bulunmasını gerektirir. Üç değiştiriciyi basılı tutarken bir tuş vuruşu ile girilebildiği için burada CM-% 'yi bir karakter olarak saydım.


3

GNU sed, 304 (-r bayrağı için 1 dahil)

Bu soruyu olası bir kopya olarak yakından oyladım, ancak bu belki de tam tersi çünkü bu cevap orada çalışmak için önemsiz bir şekilde değiştirilemez. Yine de en uzun cevap.

Esinlenerek sed belgelerinden Bu örnekte bir dizede birden çok numara işlemek için bazı iş olsa:

:d
s/9([^0-9]+|$)/_\1/g
td
s/8(_*)([^0-9]+|$)/9\1\2/g
s/7(_*)([^0-9]+|$)/8\1\2/g
s/6(_*)([^0-9]+|$)/7\1\2/g
s/5(_*)([^0-9]+|$)/6\1\2/g
s/4(_*)([^0-9]+|$)/5\1\2/g
s/3(_*)([^0-9]+|$)/4\1\2/g
s/2(_*)([^0-9]+|$)/3\1\2/g
s/1(_*)([^0-9]+|$)/2\1\2/g
s/0(_*)([^0-9]+|$)/1\1\2/g
s/(^|[^0-9_]+)(_+)/\11\2/g
y/_/0/

Çıktı:

$ for s in "teststring134this 123test string54 100" "123test" "test123" "te123st" "test 123 test" ; do echo "$s" | sed -rf incr.sed ; done
teststring135this 124test string55 101
124test
test124
te124st
test 124 test
$ 

Bunun geçici olarak _karakterler eklediğine dikkat edin , bu nedenle _giriş akışında yanlış sonuçlara yol açabilir . Bunu hafifletmek için _sed komut dosyasında bazı yazdırılamayan karakterlerle (örneğin ASCII 0x07 BEL) yer değiştirebilir ve giriş akışının yalnızca yazdırılabilir ASCII içerdiğini varsayabiliriz. Test ettiğimde bu iyi çalışıyor gibi görünüyor.



2

Lua - 68 karakter

d='(%D-)'for k,i,j in s:gmatch(d..'(%d+)'..d)do io.write(k,i+1,j)end

S cinsinden kaydedilecek girişin olmasını bekler.


2

CJam, 67 58 53 48 31 karakter

Bu soru CJam için en kötü soru gibi. Normal ifade yok, desen eşleşmesi yok, istisna yok. Ama işte başlıyoruz (#YOLO)

Sl+_A,sNerN%\[_A,s-Ner~]:)]zs1>

Bu, dizeyi sadece alfabe ve sadece rakamlar grubuna ayırır. Her basamağı arttırır ve her seferinde bir eleman alarak iki diziyi geri diker.


Önceki çözüm:

L_l{:Ci57-zA<:RC*+:N\R!N*NNW?i):NL?+RLC?@R*}/NL?

Buradan çevrimiçi deneyin

Nasıl çalışır:

Temel fikir, eğer bir rakamsa karakteri bir dizede ayrı olarak saklamak ve basamaklı olmayan bir karakter elde ettiğimizde artan değeri son dizgiye dökmektir.

L_                                               "Push two empty strings to stack,"
                                                 "first representing the final string"
                                                 "and second, the current ongoing number";
  l{                                       }/    "Run this block for each character of input string";
    :Ci                                          "Store the character to C and convert to"
                                                 "its ASCII equivalent integer";
       57-zA<:R                                  "Subtract 57 from the integer and compare"
                                                 "its absolute value with 10. Numeric character"
                                                 "would result to true here. Store the result in R";
               C*+:N                             "Take either 0 or 1 characters from C based"
                                                 "on value of R, add it to the second string"
                                                 "from first step. Also store the value in N";
                    \                            "Switch the strings. Now the string containing"
                                                 "the final result string is at top of stack";
                     R!N*                        "If the character was not a digit and N contains a number in it";
                         NNW?i):NL?+             "Convert N to number and increment it."
                                                 "If N is blank, take 0 instead. Put the final"
                                                 "value back in N and add it to the final result string";
                                    RLC?         "If the character was not a digit, push it to stack";
                                        @R*      "Put the ongoing numeric string back to top of stack";
                                             NL? "This is to handle the case when the last number"
                                                 "is not followed by a string, so stack will"
                                                 "have a string at top. Push the value of N to stack in that case";

1

Kobra - 88

do(s='')=RegularExpressions.Regex.replace(s,'\d+',do(m as Match)='[int.parse("[m]")+1]')

1

C # - 178 169 157 karakter

Bu, 999 gibi sayıların 000'a taşmasına izin verildiğini ve - +, olduğunu varsayar. E, bir sayının parçası değildir.

class T{static void Main(){var a="".ToCharArray();for(int b=1,c,i=a.Length;i-->0;b=48>c|c>57?7:b>0?c>56?a[i]='0':++a[i]*0:b)c=a[i];System.Console.Write(a);}}

Daha iyi okunabilir form:

class T
{
    static void Main()
    {
        var a="7teststring134this 123test string59 100".ToCharArray();

        for (int b=3, c, i=a.Length; i-->0;
            b=48>c|c>57
                ?7
                :b>2
                    ?c>56?a[i]='0':++a[i]*0
                    :b
        ) c=a[i];

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

Ben burada yeniyim, daha önce hiç kod golf denemedim, sadece denedim :)

Acaba daha da kısaltmak için fikirleri olan var mı ...

C # ile katılmak için, gerçek kod etrafında gerekli tüm çerçeveyi atlayabilirsek iyi olurdu - o zaman bu sadece 82 karakter ve güçlü bir sistem işlevi çağırmadan olurdu.


İşaretçilerle aynı (182 karakter):

class T
{
    unsafe static void Main()
    {
        char[] a="7teststring134this 123test string59 100".ToCharArray();

        int b=3;
        fixed (char* s=&a[0])
            for (var p=s+a.Length; p-->s; )
                b=*p<48|*p>57
                    ?7
                    :b>2
                        ?*p>56?*p='0':++*p*0
                        :b;

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

Şimdi taşma olmadan, bu 999 kasasını (223 karakter) doğru şekilde işler:

class T
{
    static void Main()
    {
        var s=new System.Text.StringBuilder("9999teststring134this 123test string99 100");

        for (int b=3, c, i=s.Length; i-->0; )
        {
            c=s[i];
            b=48>c|c>57
                ?b>8?8:7
                :b>2
                    ?c>56?c-(s[i]='0'):++s[i]*0
                    :b;
            if (b>8&i<1|b==8) s.Insert(i+9-b, '1');
        }

        System.Console.Write(s);
        System.Console.ReadKey();
    }
}

Bir başka farklı olan, standart girdiden okur ve özyineleme kullanır:

namespace System {
    using C=Console;
    class T {
        class t {
            byte b=1;
            string s="";
            void R() {
                var c=C.Read();
                if (c>31) {
                    R();
                    if (48>c|c>57) b=1;
                    else if (b==1) c=c==57?48:++c*b--;
                    s=(char)c+s;
                }
            }
            public t() {
                R();
                C.Write(s);
            }
        }
        static void Main() {
            new t();
            C.ReadKey();
        }
    }
}

Not: Console.ReadKey();ve dizenin kendisi sayılmamalıdır.

Bunu zaten birçok kez geliştirdim, yorumlara bakın. Hala daha fazla iyileştirme için yer var, söyleyebilirim :) Ve uzunluk için üzgünüm, ama farklı versiyonların onları tutacak kadar ilginç olduğunu düşünüyorum ...


hayır, "çevreden" kurtulmaya izin verilmez. Ben yerine üçlü operatör hakkında ne if(c==57)yazabilirsiniz sonra ikinci kodunuzda hesaba katmak . golf hileler bir sürü infact var. belki de codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c adresini ziyaret etmelisinizc--;c=48;
proud haskeller 23:14

Teşekkürler, golf hakkında hiçbir şey bilmiyorum :) Burada gördüğünüz her şey benim tarafımdan icat edildi ;-) 57-1 48 değil. Yani anlamıyorum.
maf-soft

Hata! :-) :-) :-) :-)
gururlu haskeller

Gerçekten C # bilmiyorum, ama sanırım onları birbirine yapıştırmak için bazı operatör kullanabilirsiniz... ? ... : c++*b--
gurur haskeller

btw size C # ipuçları yerine C ipuçlarını gönderdiğiniz için üzgünüm: codegolf.stackexchange.com/questions/173/…
proud haskeller

1

Groovy, 38 bayt

{it.replaceAll(/\d+/,{(it as int)+1})}

Uggghhh ... Kelimelerden kesinlikle nefret ediyorum replaceve allbenim için tüm regex golflerini mahvediyorlar .


1
(it as int)+1it.next()
manatwork

0

PHP - 91 Bayt

<?$i=fgets(STDIN);for($n=0;$n<strlen($i);$n++)if(is_numeric($i[$n]))$i[$n]=$i[$n]+1;echo$i;

Düzenli ifadeler kullanmak istemedim. PHP doğrudan bir dize ofsetini artırmak için yetenekli değil, bu yüzden artış adımında bazı bayt eklemek gerekiyordu. Bu tek satırlık komut dosyası PHP komut dosyası yazmanın çok karanlık bir yaşını hatırlıyor ...


Şimdi, sorunun sizden bir dizi algarizmin sonuç sayısını artırmanızı istediğini gözlemledim. Bu cevap yanlış. Ama gerçekten op'un istediği hakkında daha fazla ayrıntı eklemesi gerektiğini hissediyorum.
Alexandre Teles

0

K, 56

{" "/:{,/$(`$a)^`$$1+"I"$a:_[;x]@&~~':x in .Q.n}'" "\:x}

0

sed ve bash - 40 (çağırma ve borular dahil)

$ cat << EOF |sed 's/[0-9]\+/$((\0+1))/g;s/^/echo /'|bash
teststring134this 123test string54 100
123test
test123
te123st
test 123 test
EOF

Çıktılar:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test

Bu test dizesini denedim: 42;rm -rf /İlk kez çalıştı.
Dennis

2
Değişebilirsin \0için &, (-1 Char) $((…))için $[…], (-2 karakter) s/^/echo /için iecho \\senin kısaltmak için (-2 karakter) geçerli kod. Ancak önce @Dennis tarafından belirtilen hatayı daha iyi düzeltin. (O eğlence için ve konuyla ilgili ipucu olarak “Bu ilk kez çalıştı” yazdı Aslında kodunuzu girişi başarısız içeren. ;, #, `…`, $(…)Çok ve belki diğer özel karakterleri.)
manatwork

Rasgele kod yürütme bir özellik :-)
mgjk

Bir tür giriş kısıtlaması olmadan ve kodu küçük tutmadan bu rotaya gitmenin bir yolu olmayabilir. Çözümün doğası girdiyi çevirmek ve sed bunu yapamayacağı için matematik yapmak için bir tercüman kullanmaktır. Kullanıcı girişi bir yorumlayıcıya ulaşır ulaşmaz çıkış kaçıştır. Önceki sed örneğinden kısa, sed matematik yapamaz.
mgjk

Biraz daha kısa: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- yine de başka bir benzer soruya cevabım olarak kod enjeksiyon problemi var codegolf.stackexchange.com/a/37145/11259
Digital Trauma

0

Java 7, 119 bayt

void c(String s){for(String x:s.split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}

Gereksinim yalnızca bir işlev yerine bir programsa, 149 bayttır:

class M{public static void main(String[]a){for(String x:a[0].split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}}

Test edilmemiş ve test kodu:

Burada deneyin.

class M{
  static void c(String s){
    for(String x : s.split("(?=[^\\d]+)|(?<=[^\\d]+)")){
      System.out.print(x.matches("\\d+")
                        ? new Long(x) + 1
                        : x);
    }
  }

  public static void main(String[] a){
    c("123test");
    System.out.println();
    c("test123");
    System.out.println();
    c("te123st");
    System.out.println();
    c("test 123 test");
    System.out.println();
    c("7teststring134this 123test string59 100");
  }
}

Çıktı:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101

0

Gema, 14 karakter

<D>=@add{$1;1}

Örnek çalışma:

bash-4.3$ gema '<D>=@add{$1;1}' <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

0

DASH , 16 bayt (rakipsiz)

rstr[R"\d+""g"+1

Bu, bir işlev / kısmi uygulama döndürür.

Kullanımı:

rstr[R"\d+""g"+1]"test 123 234t"

açıklama

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]

Bu cevap rekabet etmiyor mu?
Dennis

oh rip :( Bir şekilde bunun bir katalog sorusu olduğunu düşündüm.
Mama Fun Roll

0

CJam, 18 bayt

q_A,s-_:(:`ers~]:)

Burada deneyin.

açıklama

q         e# Read input.
_A,s-     e# Duplicate and remove digits.
_         e# Duplicate.
:(:`      e# Decrement and get the string representation of each character.
er        e# Map the characters to the decremented string representation.
s~        e# Flatten to string and evaluate.
]:)       e# Wrap in an array and increment each element.

0

R, 83 bayt

Partiye geç. Girdinin değişkente saklandığını varsayar x. Bunu regmatchesçözmek için muhtemelen gerekli değildir, ancak harici paketler olmadan vektörize değiştirmeleri anlayamadım.

paste0(el(r(x,m<-gregexpr("\\d+",x),T)),c(as.numeric(el(r(x,m)))+1,""),collapse="")

Açık ve açık

r=regmatches                                        # Alias for regmatch
y=r(x<-scan(,""),m<-gregexpr("\\d+",x))             # return match digits
i=r(x,m,T)                                          # return inverted match (non-digits)
paste0(el(i),c(as.numeric(el(y))+1,""),collapse="") # join digits+1 and non-digits, element-wise

Örnek çıktı

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"

0

Komut satırı seçeneğiyle C # (Visual C # Etkileşimli Derleyici)/u:System.Text.RegularExpressions.Regex;System.Int32 , 40 bayt

Replace(n,"\\d+",m=>Parse(m.Value)+1+"")

Girdinin n adlı bir değişkende olmasını bekler.

Çevrimiçi deneyin!


2
Geçersiz, bir değişkente girdi
yalnızca ASCII-yalnızca

@ ascii-only Bu soru açıkça buna izin veriyor gibi görünüyor 'kişisel olarak, bugünün girdi standartlarına bağlı kalmaya çalışacağım
Jo King

Oh bekle: / ew bu soru
sadece ASCII sadece
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.