Сложение-вычитание чисел в строке

14

Возьмите строку в качестве ввода и выполните сложение / вычитание всех цифр в строке и выведите сумму этих операций в качестве результата.

правила

  • Цифры в строке читаются слева направо
  • Если цифра (n) нечетная, выполните сложение со следующей цифрой (n + n1)
  • Если цифра (n) четная, выполните вычитание со следующей цифрой (n - n1)
  • Если вы достигли последней цифры в строке, выполните операцию с первой цифрой в строке
  • Вывод будет суммой всех полученных значений
  • Если в строке есть только одна цифра, выполните операцию самостоятельно (n + n или nn)
  • Если в строке нет цифр, выводится 0

пример

Input: r5e6o9mm!/3708dvc    
Process: (5+6) + (6-9) + (9+3) + (3+7) + (7+0) + (0-8) + (8-5)
Output: 32

Примечания

  • Любая функция или полная программа принимаются
  • Максимальная длина ввода будет зависеть от ограничения вашего языка для строкового ввода
  • Нет ограничений на ввод символов, но только цифры полуширины учитываются при выводе
  • Побеждает несколько байтов
Нуар Антарес
источник
4
Еще пара примеров была бы хороша
Дилнан
2
Я бы рекомендовал добавить тестовый пример, заканчивающийся нечетной цифрой.
Арно
3
Похожие TestCase: "", "0","1"
TSH
1
Можем ли мы принять ввод как массив символов вместо строки? (Юлия проводит различие между этими двумя.)
sundar - Восстановить Монику
4
@sundar В настоящее время принято считать, что строка определяется как последовательность символов. Насколько я понимаю, массивы символов поэтому разрешены по умолчанию, даже если ваш язык имеет нативный тип строки .
Арно

Ответы:

6

Желе , 17 15 12 байт

fØDV€ḂT‘ịƲSḤ

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

Попробуйте тестовые случаи.

Программа сохраняет только цифры, которые следуют за нечетной цифрой, а затем вычисляет в два раза больше суммы

fØDV€ḂT‘ịƲSḤ   
f                   Remove anything that isn't...
 ØD                 a digit.
   V€               Cast each digit to an integer
         Ʋ          Monad:
     Ḃ              Parity of each digit.
      T             Indices of truthy elements (odd digits).
       ‘            Increment.
        ị           Index into list of digits.
                    Wraps to beginning and if there are no digits this returns 0.
          S         Sum.
           Ḥ        Double.
dylnan
источник
3

K (ок) , 47 43 40 31 байт

Решение:

{+/(1_x,*x)*2*2!x^:(x-:48)^!10}

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

Объяснение:

Удалите из строки все, что не является числом (при этом также конвертируя), по модулю 2, умножьте на 2, умножьте на x, повернутый на 1, и суммируйте.

{+/(1_x,*x)*2*2!x^:(x-:48)^!10} / solution
{                             } / lambda taking implicit x
                           !10  / range 0..10
                          ^     / except
                   (     )      / do this together
                    x-:48       / subtract 48 from x (type fudging char ascii value -> ints), save back into x
                x^:             / x except right, and save back to x
              2!                / modulo 2
            2*                  / multiply by 2
           *                    / multiply by
   (      )                     / do this together
        *x                      / first element of x
       ,                        / append to
      x                         / x
    1_                          / drop first (ie rotate everything by 1)
 +/                             / sum, add (+) over (/)

Наивное решение:

Удалите из строки все, что не является числом (при этом также конвертируя), возьмите 2-элементное скользящее окно, выясните, являются ли они нечетными или четными, примените при необходимости сложение / вычитание, а затем суммируйте.

{+/((-;+)2!x).'2':(1+#x)#x^:(x-:48)^!10}

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

Примечания:

  • -4 байта благодаря @ngn благодаря более умному способу фильтрации ввода
  • -3 байта , используя скользящее окно вместо изменения формы
  • -9 байт для переноса решения ngn (не наивный подход)
streetster
источник
1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
нгн
Я написал решение в q / kdb +, а затем портировал его на oK ... возможно, смогу выжать еще несколько байтов из этого!
Стритстер
1
Я разместил отдельный ответ в ngn / k, не стесняйтесь вносить идеи оттуда. Я думаю, что ОК окажется самым коротким, так как мой парсер на данный момент мусор - он не анализирует измененное назначение должным образом. Кстати, я не знал, что такое ':«скользящее окно» - интересно.
нгн
Вы, кажется, хорошо знакомы с k. Если вам когда-нибудь захочется поговорить о вещах по векторному программированию с единомышленниками или просто посмотреть, как спорят остальные из нас - у нас есть этот чат . Большая часть подшучивания относится к APL, но k и J тоже по теме.
НГН
2

Perl 6 , 41 байт

{2*sum rotate($!=.comb(/\d/))Z*(@$! X%2)}

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

Использует ту же логику, что и Jelly . Это суммирует только цифры, которые следуют за нечетным числом, а затем умножаются на 2.

Джо Кинг
источник
2

Powershell, 80 78 76 байт

($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s

-2 байта благодаря Нейлу с раствором Retina

-2 байта спасибо AdmBorkBork

Тестовый скрипт:

$f = {
($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s
}

&$f 'r5e6o9mm!/3708dvc'

объяснение

Прежде всего: добавляется 2 * n, если предыдущая цифра нечетная, и 0, если предыдущая цифра четная.

($d="$args"-split'\D*'-ne'')+ # let $d is array contains digits only, each element is a digit
$d[0]|                        # apend first digit to the end of the array
?{                            # where for each digit
    $p-match'[13579]'         # predicate is 'previous digit is odd' (it is false on the first iteration because $p is null)
    $p=$_                     # let previous digit is current
}|
%{                            # for each digit matched to the predicate
    $s+=2*$_                  # add current digit multiply 2 to $s. 
}
$s                            # return sum

Extra, 99 байт

Вдохновленный @Neil. Совпадающие цифры в регулярном выражении только с «предыдущей цифрой нечетной». Matchesэто автоматическая переменная .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s
Mazzy
источник
1
Сохраните замену байта |?{$_}на -ne''другой, перейдя $d="$args"-split'\D*'-ne''в паренсы, как ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork
2

MATL , 18 17 байт

t4Y2m)!Ut1YSof)sE

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

(-1 байт благодаря Луису Мендо / Джузеппе / обоим!)

Объяснение:

     % Implicit input
 t   % duplicate input
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc']
 4Y2 % push inbuilt literal, characters '0':'9'
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc' '0123456789']
 m)  % extract only characters from input that belong to '0':'9'
     % stack: ['5693708']
 !U  % transpose and convert each value from string to number
     % stack: [5 6 9 3 7 0 8]
 t   % duplicate that
 1YS % circular shift by 1
     % stack: [[5 6 9 3 7 0 8] [8 5 6 9 3 7 0]]
 o   % parity check - 1 for odd, 0 for even
     % stack: [[5 6 9 3 7 0 8] [0 1 0 1 1 1 0]]
 f   % find non-zero value indices in last array
     % stack: [[5 6 9 3 7 0 8] [2 4 5 6]]
 )   % index at those places in the first array
 s   % sum
 E   % multiply by 2
     % (implicit) convert to string and display

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

Я не думал, что fпосле проверки четности oбудет необходимо, но по какой-то причине MATL не видит массив нулей и единиц, которые являются результатом oлогического массива, вместо этого принимает их в качестве числовых индексов и индексов в позиции 1и end.

sundar - Восстановить Монику
источник
Я думаю, что вы можете использовать !Uвместо 48-. Транспонирование здесь, похоже, не приносит никакого вреда. oдля doubleввода просто mod(...,2), поэтому выход double. Хороший NaNтрюк с вводом! Если это должно было решить посторонний вывод в STDOUT, у Денниса была идея, и, вероятно, это скоро исправят
Луис Мендо,
!Uвместо48-
Джузеппе
@ LuisMendo, блин, ты меня побил!
Джузеппе
@Giuseppe :-D :-D
Луис Мендо
Спасибо вам обоим, отредактировано. @LuisMendo Когда oтогда вывод логического массива - или нет? (Должен признаться, я никогда не заглядывал в систему числовых типов MATLAB.) И да, я подумал, NaNчто это будет хорошим дозором, поскольку вряд ли это будет реальный ввод где-либо, но приятно знать, что он не понадобится гораздо дольше !
sundar - Восстановить Монику
2

К (нгн / к) , 33 байта

{+/(1_x,*x)*2*2!x:-48+x^x^,/$!10}

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

{ } это функция с аргументом x

!10 это список 0 1 ... 9

$ преобразовать в строки

,/ конкатенация

x^значит xбез того что справа

x^x^означает, что xпересекается с тем, что справа, то есть сохранить только цифры отx

-48+вычитать 48, который является кодом ASCII"0"

x: назначить в x

2! мод 2

2* умножить на 2

1_x,*xэто одна капля: с xпоследующим первым из x; т.е. xповернут влево на один шаг

+/ сумма

СПП
источник
2

Japt (v2.0a0), 25 19 байт

-6 байт благодаря Шегги .

kè\D
íÈ°*2*Y°u}Ué)x

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

Это работает без цифр на этот раз! Ввод представляет собой список символов.

LegionMammal978
источник
19 байт , включая переход на Japt v2. Не доволен массивом в xфункции, хотя. Звоните мне в чате, если у вас есть вопросы.
Лохматый
Подождите, просто заметил, что это не будет работать вообще, если на входе нет цифр.
Лохматый
Кроме того, где источник v2.0a0, @Shaggy? Я не могу найти это в репо.
LegionMammal978
Это v1 и это v2.
Лохматый
Если вы пропустили это в чате, я уменьшил это до 12 байт для вас.
Лохматый
2

05AB1E , 12 9 байт

Сохраняет 1 байт по сравнению с наивным методом с помощью трюка с четностью Дилнана.
Сохранено 3 байта благодаря Mr. Xcoder

þDÁ€ÉÏSO·

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

объяснение

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double
Emigna
источник
Хм, было бы þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·или þÀsþ€ÉÏSO·пройти все тестовые случаи для -2 байт?
Мистер Кскодер
@ Mr.Xcoder: Ах да. Ницца! Мы можем даже сделать þDÁ€ÉÏSO·для -3 :)
Emigna
1

Сетчатка , 37 байт

(\d).*
$&$1
L$`(?<=[13579]\D*).
2**
_

Попробуйте онлайн! Объяснение:

(\d).*
$&$1

Добавьте копию первой цифры.

L$`(?<=[13579]\D*).

Совпадение с любым, чья первая предыдущая цифра нечетная

2**

Преобразуйте все матчи в одинарные и удвойте их. (Номера цифр рассматриваются как ноль.)

_

Возьми сумму. Если совпадений не было, то при необходимости получается ноль.

Лучшее, что я мог сделать в Retina 0.8.2 - 44 байта:

[^\d]

(.).*
$&$1
(?<![13579]).

.
$*
.
..
.

Попробуйте онлайн! Объяснение:

[^\d]

Удалить не цифры.

(.).*
$&$1

Добавить копию первой цифры.

(?<![13579]).

Удалите цифры, которые не следуют за нечетной цифрой.

.
$*

Преобразовать в одинарный.

.
..

Удвой их.

.

Возьми сумму.

Нил
источник
Я боюсь, что результат будет неправильным, если последняя цифра не является странной
mazzy
1
@mazzy Когда вы произносите последнюю цифру, вы имеете в виду до или после копирования первой цифры в конец?
Нил
'к концу'. шаг «Добавить копию первой цифры» копирует до конца? Ok. круто. Спасибо
Маззи
1

JavaScript (ES6), 56 байт

Принимает ввод как массив символов.

s=>s.map(c=>1/c?r+=p*(p=c*2&2,n=n||c,c):0,n=p=r=0)|r+p*n

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

комментарии

s =>                     // given the input array s[]
  s.map(c =>             // for each character c in s[]:
    1 / c ?              //   if c is a digit:
      r +=               //     update r:
        p * (            //       p = either 0 or 2 (always 0 on the 1st iteration)
          p = c * 2 & 2, //       p = 0 if c is even, 2 if c is odd
          n = n || c,    //       if n is still equal to 0 (as an integer), set it to c
          c              //       compute p * c
        )                //     add the result to r
    :                    //   else:
      0,                 //     do nothing
    n = p = r = 0        //   n = first digit, p = previous digit, r = result
  )                      // end of map()
  | r + p * n            // compute the last operation with the 1st digit and add it to r
Arnauld
источник
1

JavaScript (Node.js) , 85 84 83 82 байта

-1 байт благодаря овсу

s=>(s.match(/\d/g)||[]).reduce((r,n,i,a)=>r+(+n)+a[a[++i]!=null?i:0]*-(1-n%2*2),0)

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

Принимает строковый ввод, находит цифры в виде массива символов или возвращает пустой массив, если ничего не найдено, а затем использует приведение типов для обеспечения правильного добавления / вычитания значений. Прямой поиск преобразует индекс в индекс и использует краткую проверку на краткость, а затем заключительная часть проверяет, является ли число нечетным или четным, чтобы затем принудительно сложить или вычесть (+ и - есть - и т. Д.)

bluefinger
источник
n-0может быть+n
овс
Добро пожаловать в PPCG!
Конор О'Брайен
1

R , 58 байт

function(x,y=strtoi(x[x%in%0:9]))sum(c(y[-1],y[1])*y%%2*2)

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

  • с помощью трюк Дилнана
  • -8 байт принимает вектор символов вместо строк
  • -3 байта благодаря @Giuseppe
digEmAll
источник
67 байт, если вы не против arrayвывода.
Джузеппе
1
хм, на самом деле вы не можете использовать скалярное произведение из-за пустого массива, xxxтак что это 68 байтов, используя изменение индексации aдля генерации y.
Джузеппе
@Giuseppe: модифицировано, спасибо :)
digEmAll
@Giuseppe: Я спрашиваю ваше мнение, потому что вы более мудрый игрок в код ... из комментариев кажется, что мы можем использовать вектор символов, в этом случае возможен 61 байт: попробуйте онлайн! что вы думаете ?
digEmAll
использовать strtoiвместо as.double, но да, это должно быть хорошо.
Джузеппе
0

Perl 5 , 48 байт

$;=$;[++$-%@;],$\+=$_%2?$_+$;:$_-$;for@;=/\d/g}{

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

Мне очень нравится, как это выглядит загадочно, но это довольно простой цикл вокруг всех чисел в строке.

Дом Гастингс
источник
0

C Sharp 180 байтов

Это не очень хороший гольф, лол.

s=>{var q=new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));q.Enqueue(q.First());int t,o=0;o=q.Dequeue();try{while(true){t+=o+(o%2==0?-1:1)*(o=q.Dequeue());}}catch{return t;}}

Ungolfed:

var q = new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));
int t,o=0;

q.Enqueue(q.First());    
o=q.Dequeue();

try{
    while(true){
        t += o + (o%2==0?-1:1) * (o=q.Dequeue());
    }
}
catch {
    return t;
}
IEatBagels
источник
0

Stax , 14 байт

ÿ←«4é■≥B▬ê→█T♥

Запустите и отладьте его

Распакованный, размазанный и прокомментированный, это выглядит так.

Vd|&    filter out non-digits
c|(\    zip into pairs after rotating right
F       for each digit pair
  B2%s  first-of-pair % 2, then swap top two stack elements
  eH*   eval digit as integer, double, then multiply
  +     add to running total

Запустите этот

рекурсивный
источник
0

JavaScript (ES6), 52 байта

s=>s.filter(t=>1/t&&~(a+=u*t,u=t%2),a=u=0)[0]*u+a<<1

Ожидается ввод в виде массива символов. Предупреждение: из-за использования сдвига битов выход имеет верхнюю границу2^31-1

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

объяснение

По существу удваивает сумму цифр после нечетных значений.

s => s.filter(             // filter to preserve the first digit
    t =>
        1/t &&             // short-circuits if NaN
        ~(                 // coerce to truthy value
            a += u * t,    // adds value only if previous digit is odd
            u = t%2        // store parity of current digit
        ),
    a = u = 0
)[0]                       // first digit
* u + a
<< 1                       // bit-shift to multiply by 2 (also coerces a NaN resulting from a string devoid of digits to 0)
избыточность
источник