Сумма целых чисел в строке, разделенных нечисловыми числами, такими как «a» и «Y»

14

Создайте программу, которая суммирует все целые числа, найденные в строке, которая установлена ​​как переменная в программе (таким образом, программе не нужно обрабатывать ввод). Целые числа разделены нечисловыми числами (все, кроме 0, 1, 2, 3 ... 9).

Примеры:

  • e7rde f ,fe 43 jfj 54f4sD = 7 + 43 + 54 + 4 = 108
  • 5 = 5
  • 64 545,5445-32JIFk0ddk = 64 + 545 + 5445 + 32 + 0 = 6086
  • 0ab0 = 0 + 0 = 0

Дополнительные примечания:

  • Поддержка Unicode не обязательна, но разрешена
  • -n(где nцелое число) не считается отрицательным n, а дефисом, за которым следует n.

Ответ может быть напечатан на экране (но не обязательно).

Самый короткий ответ (в символах) победит.

Анто
источник
Должны ли мы распечатать результат тоже? (Вы упоминаете, что нет ввода / вывода).
Догберт
@ Догберт - я не думал об этом. Извини да Я буду обновлять пост.
Anto
Изменил это, поскольку некоторые люди уже имели ответы и не хотели "причинять им боль". Думаю, мне пора спать, поэтому я подумаю немного яснее;)
Anto
2
Анто: Задача, в которой решение не имеет видимых побочных эффектов, не очень приятная.
Джои,
Интересный тестовый случай, с которым я только что столкнулся, был бы 5a-3(мой код пропустил -бы, если бы он сразу следовал за числом, но не, если бы перед ним не было числа).
Мартин Эндер

Ответы:

10

Perl, 15

Ввод $_, сумма в $c:

s/\d+/$c+=$&/ge
JB
источник
14

Ruby 1.9, 21 символ

eval a.scan(/\d+/)*?+

Чтобы напечатать решение для stdout, требуется 2 дополнительных символа:

p eval a.scan(/\d+/)*?+

И чтобы читать из стандартного ввода вместо предопределенной переменной, необходимо использовать еще 3 символа:

p eval gets.scan(/\d+/)*?+

Для Ruby 1.8 замените ?+на, "+"чтобы получить рабочее решение из 22 символов.

Ventero
источник
Предполагается, что входные данные взяты из переменной, а не из stdin. И scanкороче чем split. Таким образом, ваше решение становится eval s.scan(/\d+/)*?+- 21 символов.
sepp2k
@ sepp2k: Да, не правильно прочитал описание. Я просто привык к другим задачам по гольфу, где вам обычно приходится читать со стандартного ввода и печатать на стандартном выводе. Хороший вопрос scan, спасибо!
Ventero
+1, отличное использование evalи* '+'
Догберт
6

Python (60)

import re;print sum(map(int,filter(len,re.split(r'\D',s))))
Хоа Лонг Там
источник
5

Рубин - 36 34 символов

s.scan(/\d+/).map(&:to_i).reduce:+

36 символов, если вы хотите, чтобы результат был напечатан.

p s.scan(/\d+/).map(&:to_i).reduce:+

Предполагается, что ввод присутствует в виде строки в s.

Dogbert
источник
4

JavaScript (ES6), 30

c=0,s.replace(/\d+/g,d=>c+=+d)

Аннотированная версия:

// Store the sum.
c=0,
// Process every number found in the `s`.
s.replace(/\d+/g,
  // Convert the number into an integer.
  // Add it to the sum.
  d => c += +d
)
Флоран
источник
3

Windows PowerShell, 23 25 29 31

С выходом.

$x-replace'\D','+0'|iex

На самом деле, без вывода точно так же, вы просто отправили бы его куда-нибудь еще, где это необходимо.

детеныш
источник
2

J - 40 38 знаков

Ленивая версия. Требуется библиотека строк.

+/".(,' ',.~a.-.'0123456789')charsub y
MPelletier
источник
Поддерживает Юникод. Поддерживает кодирование, подумай об этом!
MPelletier
2

Джава

вне конкурса;)

public static long sum(String s) {
    long sum = 0;
    String p = "";
    char[] ch = s.toCharArray();
    for (int i = 0; i < ch.length; i++) {
        boolean c = false;
        if (Character.isDigit(ch[i])) {
            if (i + 1 < ch.length) {
                if (Character.isDigit(ch[i + 1])) {
                    p += ch[i];
                    c = true;
                }
            }
            if (!c) {
                p += ch[i];
                sum += Integer.valueOf(p);
                p = "";
                c = false;
            }
        }
    }
    return sum;
}
Włodar
источник
2

JavaScript [30 байт]

eval(s.match(/\d+/g).join('+'))
зрение
источник
2

Лабиринт , 29 21 байт

(Отказ от ответственности: Лабиринт новее, чем этот вызов.)

Кроме того, в Лабиринте нет переменных, поэтому я выбрал обычную программу ввода / вывода.

)_"+`
( "?"
";;,;;(!@

Это было довольно просто из-за того, как работают команды ввода Лабиринта. ?пытается прочитать подписанное целое число из STDIN и останавливается на первой не цифре. Если он не может прочитать целое число (поскольку следующий символ -не является цифрой или любой другой не цифрой, или мы достигли EOF), он вернется 0вместо этого. ,с другой стороны читает любой последующий байт и толкает значение байта. Если этот вызывается в EOF, он вернется -1вместо этого.

Итак, вот некоторый псевдокод для решения:

running total = 0
while(true)
  while(true)
    try reading a non-zero integer N with ?
    if(N < 0)
      running total -= N
    else if(N > 0)
      running total += N
    else
      break
  // We've either read a zero or hit a something that isn't a number
  try reading a character with ,
  if(that returned -1)
    break
print running total

Работа с отрицательными числами правильно усложняет это решение. Если бы не они, я бы получил 8-байтовое решение:

?+
;,;!@
Мартин Эндер
источник
1

PHP - 37

Без печати;

<?array_sum(@split("[^0-9]+",`cat`));

С печатью (38):

<?=array_sum(@split("[^0-9]+",`cat`));
Арно Ле Блан
источник
1

Perl, 16 символов

s/\d+/$r+=$&/ge;

Принимает ввод $_, вывод продолжается $r. Последняя точка с запятой является излишней, но она, вероятно, понадобится, когда программа сделает больше вещей. Добавить say$rдля вывода.

ninjalj
источник
К сожалению, я не увидел ваш точно такой же ответ, когда я написал. Хотя я считал еще один символ даже без точки с запятой.
JB
@JB: я не могу сосчитать! :П. На самом деле, я сделал ошибку echo'ing в двойных кавычках строку wc -c.
ниндзя
1

J - 23 символа

Не победитель, но мы видим довольно редкий примитив в действии.

+/".(,_=_"."0 y)}y,:' '

Разъяснение:

  • _"."0 y- Для каждого символа во входной строке yпопробуйте прочитать его как число. Если вы не можете, используйте _вместо этого значение по умолчанию (бесконечность).

  • ,_=- Проверьте каждый результат на равенство _, а затем запустите последний массив из 0 и 1 в вектор. ( "."0всегда добавляет слишком много измерений к результату, поэтому мы исправим это здесь.)

  • y,:' ' - Добавить строку пробелов под входной строкой.

  • }- Используется как здесь, }называется Item Amend , и он использует список 0 и 1 слева в качестве индексов, чтобы выбрать строку для рисования в правом аргументе. Итак, что происходит, для каждого столбца с правой стороны мы берем исходный символ, если он может быть прочитан как число, а в противном случае мы берем пространство под ним. Следовательно, мы покрываем любые нечисловые символы пробелами.

  • +/". - Теперь преобразуйте всю эту строку в список чисел и суммируйте их.

algorithmshark
источник
1

gs2, 4 байта

W#Θd

Кодируется в CP437 ; третьи байты E9.

Wчитает все числа /-?\d+/из строки, отображает абсолютное значение, dсуммы.

(gs2 тоже новее этой задачи, но его read-numsкоманда - полное совпадение.)

Линн
источник
0

Smalltalk (Smalltalk / X) (51 символ)

используя регулярное выражение:

(s regex:'\d+' matchesCollect:[:n|n asNumber])sum

wo regex:

((s asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:c|c isDigit not]) map:#asNumber)sum

вход в с

blabla999
источник
0

Р, 30

sum(scan(t=gsub("\\D"," ",x)))

Здесь xимя переменной.

Пример:

> x  <- "e7rde f ,fe 43 jfj 54f4sD"
> sum(scan(t=gsub("\\D"," ",x)))
Read 4 items
[1] 108
Свен Хоэнштейн
источник
0

Javascript - 43 символа

Я знаю, что это долго, но не было решения JS, так что :)

c=0
a=a.split(/[^\d]/g)
for(i in a)c+=+a[i]

aэто строка cсодержит ответ.

Гауранг Тандон
источник
0

Tcl, 30

expr [regsub -all \\D+ $a.0 +]

Предполагается, что вход находится в переменной $a(формально, в a) и сохраняет ответ в результате интерпретатора. Ввод / вывод оставлен в качестве упражнения.

Donal Fellows
источник
0

APL, 16 байт

{+/⍎b\⍵/⍨b←⍵∊⎕d}

⎕dявляется встроенным, содержащим цифры (0-9). bприсваивается вектору 0/1, где 1 дается символам, которые являются цифрами. bиспользуется для сжатия заданного массива символов, а затем повторно используется для его расширения, который вставляет пробелы. это eval APL, который в этом случае преобразует строку в вектор целых чисел. +/вычисляет сумму.

lstefano
источник
Равная длина, но интересная:+/2⊃⍞⎕VFI⍨⎕AV~⎕D
Адам
0

Свифт 3, 78

s.characters.split{!("0"..."9"~=$0)}.flatMap{Int(String($0))}.reduce(0){$0+$1}

где sстрока

Kametrixom
источник
0

Perl - 24 символа

warn eval join'+',/\d+/g

Ввод в $ _

Kaundur
источник
0

На самом деле, 14 байтов (не конкурирующих)

9u▀8╙r♂┌-@s♂≈Σ

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

Это представление не является конкурирующим, потому что на самом деле это немного новее, чем этот вызов.

Эта программа поддерживает кодовую страницу CP437 для ввода.

Объяснение:

9u▀8╙r♂┌-@s♂≈Σ
9u▀             base 10 digits (0-9)
   8╙r♂┌        all characters in CP437 (map(ord_cp437, range(2**8)))
        -       set difference
         @s     split input on any value in the resulting list
           ♂≈Σ  convert to ints and sum
Mego
источник
0

С 100

t=0;main(i,v)char**v;{for(char*q,*s=v[1];i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}

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

Более ранняя 85-байтовая версия, которая немного обманывает путем жесткого кодирования строки внутри программы:

t=0;main(i){for(char*q,*s;i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}

Чтобы фактически использовать 85-байтовую программу, вам нужно присвоить переменную следующим образом:

t=0;main(i){for(char*q,*s="text";i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);}
Джерри Иеремия
источник