Сума цілих чисел у рядку, розділених нечисловими числами, такими як '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.

Відповідь може бути надрукована на екрані (але не обов’язково).

Найкоротша відповідь (у символах) виграти.


Чи слід також надрукувати результат? (Ви не згадуєте жодного вводу-виводу).
Wile E. Coyote

@Dogbert - Я про це не думав. Вибачте, так. Я оновлю пост.
Анто

Змінили це, оскільки деякі люди вже мали відповіді, і не хотіли "нашкодити" їм. Напевно, я повинен спати зараз, тому я подумаю трохи чіткіше;)
Анто

2
Анто: Завдання, де рішення не має спостережуваних побічних ефектів, не дуже приємно.
Джої

Цікавий тестовий випадок, на який я щойно зіткнувся, 5a-3мій (мій код буде пропущений, -якщо він одразу слідує за номером, але не, якщо перед ним було не число).
Мартін Ендер

Відповіді:


10

Перл, 15

Введіть $_, суму в $c:

s/\d+/$c+=$&/ge

14

Рубін 1,9, 21 символ

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

Для друку рішення для stdout потрібні 2 додаткові символи:

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

А для читання з stdin замість використання попередньо визначеної змінної необхідно використовувати ще 3 символи:

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

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


Вхід повинен братись із змінної, а не stdin. Також scanкоротше, ніж split. Так ваше рішення стає eval s.scan(/\d+/)*?+- 21 символ.
sepp2k

@ sepp2k: Так, опис не прочитав правильно. Я просто звик до інших завдань з гольфу, де вам зазвичай доводиться читати з stdin і друкувати в stdout. Хороший момент scan, дякую!
Вентеро

+1, велике використання evalта* '+'
Wile E. Coyote


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

Підтримується Unicode. Підтримує кодування, подумайте про це!
MPelletier

2

Java

поза конкурсом;)

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: Я не можу порахувати! : P. Насправді я допустив помилку повторюючи подвійну цитовану рядок wc -c.
ніндзя

1

J - 23 char

Не переможець, але ми можемо побачити досить рідкісного примітиву в дії.

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

Пояснили:

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

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

  • y,:' ' - Додайте ряд пробілів під вхідним рядком.

  • }- Використовується як тут, }називається Item Amend , і він використовує список 0s та 1s зліва в якості індексів для вибору рядка, з якого буде виведено правильний аргумент. Отже, що трапляється, це те, що для кожного стовпця в правій частині ми беремо оригінальний символ, якщо його можна було прочитати як число, а в іншому випадку ми займемо простір під ним. Отже, ми приховуємо будь-які нечислові символи пробілами.

  • +/". - Тепер перетворіть весь цей рядок у список чисел та підсумовуйте їх.


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

R, 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

Насправді 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

C 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.