Увеличивать каждое число в строке

11

Дана строка, содержащая десятичные числа:

teststring134this 123test string54 100

увеличивайте каждое число в этой строке на единицу, чтобы дать новую строку

teststring135this 124test string55 101,

Строка может быть представлена ​​как:

  • аргумент командной строки
  • STDIN
  • жестко закодированная переменная или аргумент функции

Закройте все возможные позиции для номера:

  • в качестве префикса для слова; 123test124test
  • в качестве суффикса для слова; test123test124
  • внутри слова; te123stte124st
  • один test 123 testtest 124 test

Вот не-решение для гольфа в 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'))

Это code-golfвопрос, самый короткий код выигрывает.

The6P4C
источник
5
Забавный факт: это можно сделать с помощью трех чистых подстановок регулярных выражений (без обратных вызовов) stackoverflow.com/questions/12941362/… (хотя это не самый лучший способ игры в гольф)
Martin Ender
4
Вы указали ввод, но не вывод. Из вашей входной спецификации я предполагаю, что STDOUT и и возвращаемое значение в порядке. Но можем ли мы также сохранить результат в жестко закодированной переменной (так же, как мы можем получить от нее информацию)?
Мартин Эндер
1
Как насчет ношения? Что происходит с 999?
пушистый
3
возможно дублирование умножения всех чисел в строке
Digital Trauma
7
А как насчет отрицательных чисел? Как насчет чисел с десятичной точкой? Как насчет чисел с десятичной запятой и ничего до него (кроме, возможно, со знаком минус)?
Питер Тейлор

Ответы:

23

Perl, 14 байт

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

Требуется -pпереключатель, который я посчитал одним байтом.

Пример запуска

$ perl -p <(echo 's/\d+/$&+1/ge') <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
Деннис
источник
5
Очень похоже на мой ответ здесь хаха codegolf.stackexchange.com/a/37113/29438
hmatt1
12

Рубин, 30 24 байта

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

Ожидает, что вход будет сохранен в s.

Мартин Эндер
источник
3
Не может $1.nextбыть использован в блоке?
август
@ Август, хорошо, спасибо! Я не знал, nextчто это было сложно.
Мартин Эндер
11

Vim - 13 нажатий клавиш

0qqqqq^Al@qq@q

Ожидается, что вход будет текущей строкой.

Или для конечного числа чисел (например, 999) при нажатии клавиш 8 + ceil (log (n)):

0qq^Alq999@q
coyotebush
источник
Кажется, я не могу заставить это работать .... (я использую vim 7.0.237)
Джерри Иеремия
10

JavaScript (ES6) - 28

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

Запустите с помощью H("test 123 234t").

soktinpk
источник
1
Вы можете H=удалить и просто сделать это анонимной функцией.
Mama Fun Roll
8

Perl, 23

Предполагается, что входная строка назначена $_

s/\d+/@{[$&+1]}/g;print
GRC
источник
8

Python 2 - 59

Введите строку в качестве переменной n

import re;print re.sub('\d+',lambda x:`int(x.group())+1`,n)
Бета распад
источник
6

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

Редактировать: и GCC 4.9.0 (с -std = c99), и Visual C ++ 2013 успешно создают (с предупреждениями) один и тот же код без включений. Я не знал, что ты мог сделать это! Спасибо за подсказку.

Редактировать: мне даже не пришло в голову, что я должен записать это на экран на лету вместо того, чтобы создать строку и затем распечатать ее. Это имеет огромное значение. Спасибо Деннис!

При этом используется жестко закодированная строка, но ее содержимое не учитывается в общей сумме (= "" считается).

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

В основном он проходит по строке по одному символу за раз, проверяя каждый, является ли он целым числом. Если это так, то он увеличивает целое число и записывает его в вывод, в противном случае он копирует текущий символ в вывод.

Это приводит к утечке жестко закодированной строки, поскольку она увеличивает s.

Джерри Иеремия
источник
1
Я уверен, что вы можете избавиться от некоторых из includes, и он все равно будет прекрасно компилироваться с gcc.
Мартин Эндер
1
Будет ли это работать со строкой, содержащей например 99?
анатолиг
@ MartinBüttner: Да, но тогда это не будет действительный C, только то, что работает с gcc.
R .. GitHub ОСТАНОВИТЬ ЛЬДА
@R .. Это, как правило, разрешено на PPCG. Я видел (и впоследствии делал) это довольно часто, и никто не жаловался.
Мартин Эндер
Да, и это вообще моя мозоль. Язык должен быть указан как «GCC» или «C на [конкретная арка / и т. Д., С которыми работают хаки») или аналогичный, а не C, если это на самом деле не действительно C. :-)
R .. GitHub STOP ПОМОЩЬ ЛЕД
5

J (20)

Ожидает, что вход будет сохранен в переменной a.

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

Тест:

   a=:'teststring134this 123test string54 100'
   '\d+'>:&.".rxapply a
teststring135this 124test string55 101
Мэринус
источник
5

(f?) lex (39)

Файл inc.l:

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

Обобщение:

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

Бег:

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

Я не проверял это с оригиналом lex. Комментарии приветствуются.


источник
1
Вы можете отбросить трейлинг, %%поскольку это не код пользователя: flex.sourceforge.net/manual/…
Джош,
Эй ... да! Я пытался, но без завершающего символа новой строки, и это не удалось ... тогда я не пытался добавить последний перевод строки ... ;-) ... глупая ошибка!
3

Emacs - 20 персонажей

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

Требует обработки текста для присутствия в текущем буфере. Здесь я посчитал CM-% одним символом, поскольку его можно вводить одним нажатием клавиши при удержании трех модификаторов.

user16727
источник
3

GNU sed, 304 (включая 1 для флага -r)

Я близко проголосовал за этот вопрос как за возможный дубликат, но это, возможно, противоречит этому, потому что этот ответ не может быть тривиально изменен, чтобы работать там. Безусловно, самый длинный ответ.

Вдохновленный этим примером из документации sed , хотя для обработки нескольких чисел в строке потребовалась некоторая работа:

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

Выход:

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

Обратите внимание, что это временно вставляет _символы, поэтому может привести к неправильным результатам, если они есть _во входном потоке. _Чтобы избежать этого, мы можем заменить скрипт в sed некоторым непечатным символом (например, ASCII 0x07 BEL) и предположить, что входной поток содержит только печатный ASCII. Кажется, это работает нормально, когда я проверяю это.

Цифровая травма
источник
3

Ракетка 74

(define(f x)(regexp-replace* #px"\\d+"x(λ(m)(~a(+ 1(string->number m))))))
Мэтью Баттерлик
источник
2

Луа - 68 персонажей

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

Ожидает, что вход будет сохранен в s.

AndoDaan
источник
2

CJam, 67 58 53 48 31 символов

Этот вопрос как худший вопрос для CJam. Без регулярных выражений, без сопоставления с образцом, без ловли исключений. Но здесь мы идем (#YOLO)

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

Этот разбивает строку на группы только из букв и цифр. Увеличивает каждую цифру и сшивает два массива по одному элементу за раз.


Предыдущее решение:

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

Попробуйте онлайн здесь

Как это работает:

Основная идея состоит в том, чтобы хранить символ отдельно в строке, если это цифра, и выгружать увеличенное значение в окончательную строку, как только мы получим нецифровый символ.

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

Кобра - 88

do(s='')=RegularExpressions.Regex.replace(s,'\d+',do(m as Match)='[int.parse("[m]")+1]')
Οurous
источник
1

C # - 178 169 157 символов

Это предполагает, что числа типа 999 могут переполняться до 000 и что - +, E не являются частью числа.

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

Лучше читаемая форма:

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

Я новичок здесь, никогда не пробовал код гольф раньше, просто попробовал :)

Интересно, есть ли у кого-нибудь идеи, чтобы сделать его еще короче ...

Для участия в C # было бы неплохо, если бы мы могли опустить всю необходимую структуру вокруг реального кода - тогда это будет иметь только 82 символа, и это без вызова каких-либо мощных системных функций.


То же самое с указателями (182 символа):

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

Теперь без переполнения это правильно обрабатывает случай 999 (223 символа):

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

Другой, более старый, читает со стандартного ввода и использует рекурсию:

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

Замечания: Console.ReadKey(); и сама строка не должна учитываться.

Я улучшил это уже несколько раз, смотрите комментарии. Я бы сказал, что еще есть возможности для улучшений :) И извините за длину, но я думаю, что разные версии достаточно интересны, чтобы держать их ...

МАФ-мягкий
источник
нет, избавление от "среды" не допускается. я полагаю в вашем втором коде после if(c==57)того, как вы могли бы написать c--;вместо того c=48;, как насчет троичного оператора тоже. Существует множество игровых трюков. может быть, вам стоит посетить codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
гордый haskeller
Спасибо, я ничего не знаю о гольфе :) все, что вы видите здесь, было изобретено мной ;-) 57-1 не 48. Так что я не понимаю.
маф-софт
Упс :-) :-) :-) :-)
гордый haskeller
Я не очень хорошо знаю C #, но я думаю, что вы можете использовать какой-нибудь оператор, чтобы ... ? ... : c++*b--
склеить
Кстати, извините за отправку вам советов C вместо советов C #: codegolf.stackexchange.com/questions/173/…
гордый haskeller,
1

Groovy, 38 байт

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

Я просто ненавижу эти слова, replaceи allони разрушают для меня все регулярные игры в гольф.

Урна волшебного осьминога
источник
1
(it as int)+1it.next()
manatwork
0

PHP - 91 байт

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

Я не хотел использовать регулярные выражения. PHP не способен напрямую увеличивать смещение строки, поэтому мне нужно было добавить несколько байтов на шаге увеличения. Этот однострочный скрипт помнит меня очень мрачный век сценариев PHP ...

Александр Телес
источник
Я только что заметил, что вопрос просит вас увеличить число результатов последовательности алгаризмов. Этот ответ неверен. Но я действительно чувствую, что оп должен добавить больше деталей о том, что он хочет.
Александр Телес
0

К, 56

{" "/:{,/$(`$a)^`$$1+"I"$a:_[;x]@&~~':x in .Q.n}'" "\:x}
tmartin
источник
0

sed and bash - 40 (включая вызов и трубы)

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

Выходы:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test
mgjk
источник
Я попробовал эту тестовую строку: 42;rm -rf /она сработала с первого раза.
Деннис
2
Вы можете изменить \0до &(-1 полукокса), $((…))до $[…](-2 символов), s/^/echo /до iecho \\(-2 символов) , чтобы сократить ваш текущий код. Однако лучше сначала исправить ошибку, упомянутую @Dennis. (Он писал : «Он работал в первый раз» для удовольствия и , как намек на вопрос На самом деле ваш код не на входе , содержащий. ;, #, `…`, $(…)И , возможно , другие специальные символы тоже.)
manatwork
Выполнение произвольного кода - это особенность :-)
mgjk
Возможно, не будет никакого пути пойти по этому пути без каких-либо ограничений ввода и сохранения крошечного кода. Суть решения заключается в том, чтобы перевести ввод и использовать интерпретатор для выполнения математических операций, поскольку sed не может этого сделать. Как только пользовательский ввод попадает в интерпретатор, экранирование становится чокнутым. Если не считать предыдущего примера sed, sed не умеет заниматься математикой.
mgjk
Несколько короче: eval echo `sed 's/[0-9]\+/$[&+1]/g'`- все еще есть проблема с внедрением кода, хотя, согласно моему ответу на другой похожий вопрос, codegolf.stackexchange.com/a/37145/11259
Цифровая травма
0

Java 7, 119 байт

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

Если требование - это программа, а не просто функция, то это 149 байт:

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

Ungolfed & тестовый код:

Попробуй это здесь.

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

Выход:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101
Кевин Круйссен
источник
0

Гема, 14 знаков

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

Образец прогона:

bash-4.3$ gema '<D>=@add{$1;1}' <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101
manatwork
источник
0

DASH , 16 байт (неконкурентный)

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

Это возвращает функцию / частичное применение.

Использование:

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

объяснение

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]
Mama Fun Roll
источник
Этот ответ не конкурирующий?
Деннис
ой рип :( Я почему-то думал, что это был вопрос каталога.
Мама Ролл Fun
0

CJam, 18 байт

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

Попробуй это здесь.

объяснение

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.
jimmy23013
источник
0

R, 83 байта

Поздно на вечеринку. Предполагается, что ввод хранится в переменной x. Вероятно, это не нужно использовать regmatchesдля решения этой проблемы, но я не мог найти векторизованные замены без каких-либо внешних пакетов.

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

Разгромил и объяснил

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

Пример вывода

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"
Billywob
источник
0

C # (интерактивный компилятор Visual C #) с параметром командной строки /u:System.Text.RegularExpressions.Regex;System.Int32, 40 байт

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

Ожидается, что вход будет в переменной с именем n.

Попробуйте онлайн!

Воплощение невежества
источник
2
Неверный, не может ожидать ввода в переменную
только ASCII
@ ascii-only Этот вопрос явно разрешает это, хотя лично я постараюсь придерживаться сегодняшних стандартов ввода
Джо Кинг,
Ой, подождите: / EW этот вопрос
только ASCII