Tăng mỗi số trong một chuỗi


11

Cho một chuỗi chứa số thập phân:

teststring134this 123test string54 100

tăng từng số trong chuỗi này lên một để đưa ra chuỗi mới

teststring135this 124test string55 101.

Chuỗi có thể được cung cấp như:

  • một đối số dòng lệnh
  • STDIN
  • một biến số hoặc đối số hàm được mã hóa cứng

Bao gồm tất cả các vị trí có thể cho một số:

  • làm tiền tố cho một từ; 123test124test
  • như một hậu tố cho một từ; test123test124
  • bên trong một từ; te123stte124st
  • một mình test 123 testtest 124 test

Đây là một giải pháp không chơi gôn trong Python:

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'))

Đây là một code-golfcâu hỏi, mã ngắn nhất sẽ thắng.


5
Sự thật thú vị: điều này có thể được thực hiện với 3 lần thay thế regex thuần túy (không gọi lại) stackoverflow.com/questions/12941362/ trộm (đó sẽ không phải là cách chơi gôn nhất)
Martin Ender

4
Bạn đã chỉ định đầu vào nhưng không đầu ra. Từ thông số kỹ thuật đầu vào của bạn, tôi giả sử cả STDOUT và giá trị trả về đều ổn. Nhưng chúng ta cũng có thể lưu trữ kết quả trong một biến mã hóa cứng (giống như chúng ta có thể lấy đầu vào từ nó)?
Martin Ender

1
Còn mang thì sao? Điều gì xảy ra với 999?
fluffy


7
Còn số âm thì sao? Còn những con số có dấu thập phân thì sao? Còn những con số có dấu thập phân và không có gì trước nó (ngoại trừ dấu trừ) thì sao?
Peter Taylor

Câu trả lời:


23

Perl, 14 byte

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

Yêu cầu -pchuyển đổi, mà tôi đã tính là một byte.

Chạy ví dụ

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

5
Rất giống với câu trả lời của tôi ở đây haha codegolf.stackexchange.com/a/37113/29438
hmatt1

12

Ruby, 30 24 byte

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

Dự kiến ​​đầu vào sẽ được lưu trữ trong s.


3
Không thể $1.nextđược sử dụng trong khối?
tháng 8

@August đẹp, cảm ơn! Tôi không biết nextlà tinh vi.
Martin Ender

11

Vim - 13 tổ hợp phím

0qqqqq^Al@qq@q

Dự kiến ​​đầu vào là dòng hiện tại.

Hoặc đối với nhiều số (ví dụ 999) trong tổ hợp phím 8 + ceil (log (n)):

0qq^Alq999@q

Tôi dường như không thể làm cho công việc này .... (Tôi đang sử dụng vim 7.0.237)
Jerry Jeremiah

10

JavaScript (ES6) - 28

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

Chạy bằng cách sử dụng H("test 123 234t").


1
Bạn có thể lấy ra H=và chỉ cần có một chức năng ẩn danh.
Mama Fun Roll

8

Perl, 23

Giả sử chuỗi đầu vào được gán cho $_

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

8

Con trăn 2 - 59

Cung cấp chuỗi dưới dạng biến n

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

6

C99 - 86 (GCC 4.9.0 và Visual C ++ 2013)

Chỉnh sửa: Cả GCC 4.9.0 (với -std = c99) và Visual C ++ 2013 được xây dựng thành công (có cảnh báo) cùng một mã mà không bao gồm. Tôi không biết bạn có thể làm điều đó! Cảm ơn đã gợi ý.

Chỉnh sửa: Tôi thậm chí không nghĩ rằng tôi nên viết nó ra màn hình một cách nhanh chóng thay vì tạo chuỗi và sau đó in nó. Điều đó tạo ra một sự khác biệt rất lớn. Cảm ơn Dennis!

Điều này đang sử dụng một chuỗi mã hóa cứng nhưng nội dung của chuỗi không được tính vào tổng số (= "" được tính).

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

Về cơ bản, nó chạy qua chuỗi một ký tự một lần để kiểm tra từng ký tự để xem nó có phải là số nguyên không. Nếu có thì nó sẽ tăng số nguyên và ghi nó vào đầu ra nếu không nó sẽ sao chép ký tự hiện tại vào đầu ra.

Điều này làm rò rỉ chuỗi mã hóa cứng vì nó tăng s.


1
Tôi chắc rằng bạn có thể thoát khỏi một số includes và nó vẫn sẽ biên dịch tốt với gcc.
Martin Ender

1
Điều này sẽ làm việc với một chuỗi chứa ví dụ 99?
anatolyg

@ MartinBüttner: Có nhưng sau đó nó sẽ không hợp lệ C, chỉ là một cái gì đó xảy ra để làm việc trên gcc.
R .. GitHub DỪNG GIÚP ICE

@R .. Điều đó thường được cho phép trên PPCG. Tôi đã thấy (và sau đó đã thực hiện) nó khá thường xuyên mà không có ai phàn nàn.
Martin Ender

Vâng, và đó là một tiểu chung của tôi. Ngôn ngữ nên được liệt kê là "GCC" hoặc "C trên [vòm cụ thể / v.v. các hack xảy ra để hoạt động]" hoặc tương tự, thay vì C, nếu nó không thực sự hợp lệ C. :-)
R .. GitHub STOP GIÚP ICE

5

J (20)

Dự kiến ​​đầu vào sẽ được lưu trữ trong biến a.

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

Kiểm tra:

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

5

(f?) lex (39)

Tập tin inc.l:

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

Biên dịch:

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

Chạy:

$ 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 :-)

Tôi đã không kiểm tra điều này với bản gốc lex. Bình luận được chào đón.


1
Bạn có thể bỏ dấu vết %%vì đây không phải là mã người dùng: flex.sourceforge.net/manual/ Khăn
Josh

Này ... vâng! Tôi đã thử nhưng không theo dõi dòng mới và thất bại ... sau đó tôi đã không thử thêm dòng mới cuối cùng ... ;-) ... sai lầm ngu ngốc!

3

Emacs - 20 ký tự

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

Yêu cầu văn bản được xử lý để có mặt trong bộ đệm hiện tại. Tôi đã tính CM-% là một ký tự ở đây vì nó có thể được nhập bằng một lần nhấn phím khi giữ ba phím bổ trợ.


3

GNU sed, 304 (bao gồm 1 cờ -r)

Tôi đã bình chọn chặt chẽ câu hỏi này như một bản sao có thể, nhưng điều này có lẽ trái ngược với câu hỏi đó bởi vì câu trả lời này không thể thay đổi một cách tầm thường để làm việc ở đó. Cho đến nay câu trả lời dài nhất mặc dù.

Lấy cảm hứng từ ví dụ này từ tài liệu sed , mặc dù nó cần một số công việc để xử lý nhiều số trong một chuỗi:

: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/

Đầu ra:

$ 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
$ 

Lưu ý điều này tạm thời chèn các _ký tự, do đó có thể dẫn đến kết quả không chính xác nếu có _trong luồng đầu vào. Để giảm thiểu điều này, chúng ta có thể thay thế _tập lệnh sed bằng một số ký tự không in được (ví dụ ASCII 0x07 BEL) và giả sử luồng đầu vào chỉ chứa ASCII có thể in được. Điều này dường như hoạt động tốt khi tôi kiểm tra nó.


3

Vợt 74

(define(f x)(regexp-replace* #px"\\d+"x(λ(m)(~a(+ 1(string->number m))))))

2

Lua - 68 ký tự

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

Dự kiến ​​đầu vào sẽ được lưu trữ trong s.


2

CJam, 67 58 53 48 31 ký tự

Câu hỏi này giống như câu hỏi tồi tệ nhất đối với CJam. Không regex, không khớp mẫu, không bắt ngoại lệ. Nhưng ở đây chúng tôi đi (#YOLO)

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

Cái này chia chuỗi trong nhóm chỉ bảng chữ cái và chỉ chữ số. Số gia tăng mỗi chữ số và khâu lại hai mảng lấy một phần tử của mỗi phần.


Giải pháp trước đây:

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

Dùng thử trực tuyến tại đây

Làm thế nào nó hoạt động:

Ý tưởng cơ bản là tiếp tục lưu trữ ký tự riêng biệt trong một chuỗi nếu đó là một chữ số và chuyển giá trị tăng dần sang chuỗi cuối cùng sau khi chúng ta nhận được một ký tự không phải là chữ số.

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

Rắn hổ mang - 88

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

1

C # - 178 169 157 ký tự

Điều này giả định rằng các số như 999 được phép tràn tới 000 và - +, E không phải là một phần của số.

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);}}

Hình thức dễ đọc hơn:

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();
    }
}

Tôi mới ở đây, chưa bao giờ thử chơi golf code trước đây, hãy thử xem :)

Tôi tự hỏi nếu có ai có ý tưởng để làm cho nó thậm chí ngắn hơn ...

Để tham gia với C #, thật tuyệt nếu chúng ta có thể bỏ qua tất cả các khung cần thiết xung quanh mã thực tế - thì điều này sẽ chỉ có 82 ký tự và không có chức năng hệ thống mạnh mẽ nào.


Tương tự với con trỏ (182 ký tự):

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();
    }
}

Bây giờ không tràn, điều này xử lý chính xác trường hợp 999 (223 ký tự):

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();
    }
}

Một cái khác cũ hơn, nó đọc từ đầu vào tiêu chuẩn và sử dụng đệ quy:

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();
        }
    }
}

Lưu ý: Console.ReadKey();và chuỗi không nên được tính.

Tôi đã cải thiện điều này nhiều lần, xem ý kiến. Vẫn còn chỗ để cải tiến nhiều hơn, tôi sẽ nói :) Và xin lỗi về độ dài, nhưng tôi nghĩ các phiên bản khác nhau đủ thú vị để giữ chúng ...


không, thoát khỏi "môi trường" không được phép. Tôi nghĩ trong mã thứ hai của bạn sau khi if(c==57)bạn có thể viết c--;thay vì c=48;, điều gì về toán tử ternary quá. có rất nhiều thủ thuật chơi gôn. có lẽ bạn nên truy cập codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
tự hào

Cảm ơn, tôi không biết gì về golf :) mọi thứ bạn thấy ở đây đều do tôi phát minh ra ;-) 57-1 không phải là 48. Vì vậy tôi không hiểu.
maf-soft

Rất tiếc :-) :-) :-) :-)
tự hào

Tôi thực sự không biết rõ về C #, nhưng tôi đoán bạn có thể sử dụng một số toán tử để gắn kết chúng lại với nhau như... ? ... : c++*b--
tự hào

btw xin lỗi vì đã gửi cho bạn các mẹo C thay vì các mẹo C #: codegolf.stackexchange.com/questions/173/ mẹo
haskeller kiêu hãnh

1

Groovy, 38 byte

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

Uggghhh ... Tôi hoàn toàn ghét những từ đó replaceall, họ phá hỏng tất cả các sân golf regex cho tôi.


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

0

PHP - 91 byte

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

Tôi không muốn sử dụng các biểu thức thông thường. PHP không có khả năng trực tiếp tăng phần bù chuỗi, vì vậy, tôi cần thêm một số byte vào bước tăng. Kịch bản một dòng này ghi nhớ cho tôi một thời kỳ rất đen tối của kịch bản PHP ...


Tôi vừa mới quan sát thấy câu hỏi yêu cầu bạn tăng số kết quả của một chuỗi các phép thuật. Câu trả lời này không chính xác. Nhưng tôi thực sự cảm thấy rằng các op nên thêm chi tiết về những gì anh ấy muốn.
Kính thiên văn Alexandre

0

K, 56

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

0

sed và bash - 40 (bao gồm cả lời mời và đường ống)

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

Đầu ra:

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

Tôi đã thử chuỗi thử nghiệm này: 42;rm -rf /Nó hoạt động lần đầu tiên.
Dennis

2
Bạn có thể thay đổi \0thành &(-1 char), $((…))thành $[…](-2 ký tự), s/^/echo /thành iecho \\(-2 ký tự) để rút ngắn mã hiện tại của bạn . Tuy nhiên, sửa lỗi tốt hơn được đề cập bởi @Dennis trước tiên. (Ông viết “Nó làm việc lần đầu tiên” cho vui và như gợi ý về vấn đề này thực tế mã của bạn không thành công trên đầu vào chứa. ;, #, `…`, $(…)Và ký tự đặc biệt có lẽ khác nữa.)
manatwork

Thực thi mã tùy ý là một tính năng :-)
mgjk

Có thể không có cách nào để đi tuyến đường này mà không có một số loại hạn chế đầu vào và giữ cho mã nhỏ. Bản chất của giải pháp là dịch đầu vào và sử dụng trình thông dịch để làm toán vì sed không thể làm được. Ngay khi đầu vào của người dùng chạm vào một trình thông dịch, việc thoát là các hạt. Nói ngắn gọn về ví dụ sed trước đây, sed không thể làm toán.
mgjk

Tuy nhiên, phần nào ngắn hơn: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- vẫn có vấn đề tiêm mã, theo câu trả lời của tôi cho một câu hỏi tương tự khác codegolf.stackexchange.com/a/37145/11259
Chấn thương kỹ thuật số

0

Java 7, 119 byte

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

Nếu yêu cầu là một chương trình thay vì chỉ là một hàm, thì đó là 149 byte:

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);}}

Mã thử nghiệm & mã hóa:

Hãy thử nó ở đây.

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");
  }
}

Đầu ra:

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

0

Gema, 14 ký tự

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

Chạy mẫu:

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

0

DASH , 16 byte (không lọc)

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

Điều này trả về một chức năng / ứng dụng một phần.

Sử dụng:

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

Giải trình

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

Là câu trả lời này không cạnh tranh?
Dennis

oh rip :( Tôi bằng cách nào đó nghĩ rằng đây là một câu hỏi về danh mục.
Mama Fun Roll

0

CJam, 18 byte

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

Hãy thử nó ở đây.

Giải trình

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 byte

Đi dự tiệc muộn. Giả sử đầu vào được lưu trữ trong biến x. Có lẽ không cần sử dụng regmatchesđể giải quyết vấn đề này nhưng tôi không thể tìm ra sự thay thế véc tơ mà không có bất kỳ gói bên ngoài nào.

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

Ung dung và giải thích

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

Ví dụ đầu ra

input: 
"teststring135this 124test string55 101"

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

0

C # (Trình biên dịch tương tác Visual C #) với tùy chọn dòng lệnh /u:System.Text.RegularExpressions.Regex;System.Int32, 40 byte

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

Dự kiến ​​đầu vào là một biến có tên n.

Hãy thử trực tuyến!


2
Không hợp lệ, không thể mong đợi đầu vào trong một biến
ASCII

@ ascii-only Câu hỏi này dường như cho phép rõ ràng 'mặc dù về mặt cá nhân, tôi sẽ cố gắng tuân theo các tiêu chuẩn đầu vào ngày nay
Jo King

Đợi đã: / ew câu hỏi này
ASCII - chỉ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.