Сумма целых чисел в строке, разделенных нечисловыми числами, такими как «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(мой код пропустил -бы, если бы он сразу следовал за числом, но не, если бы перед ним не было числа).
Мартин Эндер

Ответы:



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 символов.


Предполагается, что входные данные взяты из переменной, а не из stdin. И scanкороче чем split. Таким образом, ваше решение становится eval s.scan(/\d+/)*?+- 21 символов.
sepp2k

@ sepp2k: Да, не правильно прочитал описание. Я просто привык к другим задачам по гольфу, где вам обычно приходится читать со стандартного ввода и печатать на стандартном выводе. Хороший вопрос scan, спасибо!
Ventero

+1, отличное использование evalи* '+'
Догберт


5

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

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

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

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

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


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

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


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

Perl, 16 символов

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

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


К сожалению, я не увидел ваш точно такой же ответ, когда я написал. Хотя я считал еще один символ даже без точки с запятой.
JB

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

1

J - 23 символа

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

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

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

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

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

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

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

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


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

вход в с


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) и сохраняет ответ в результате интерпретатора. Ввод / вывод оставлен в качестве упражнения.


0

APL, 16 байт

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

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


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

0

Свифт 3, 78

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

где sстрока



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

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);}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.