Додавання-віднімання чисел у межах рядка


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
Ще кілька прикладів були б непоганими
dylnan

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.

3

К (оК) , 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!x).'2':(1+#x)#x^:(x-:48)^!10}

Спробуйте в Інтернеті!

Примітки:

  • -4 байти завдяки @ngn завдяки розумнішому способу фільтрації вхідних даних
  • -3 байти за допомогою розсувного вікна, а не переформатування
  • -9 байт, що передають рішення ngn (не наївний підхід)

1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
ngn

Я написав рішення в q / kdb +, потім переніс в oK ... можливо, вдасться вичавити ще кілька байтів з цього!
Стрітер

1
Я розмістив окрему відповідь в ngn / k, не соромтеся надсилати ідеї звідти. Я думаю, що ОК в кінцевому підсумку виявиться найкоротшим, оскільки мій аналізатор зараз є сміттям - він не розбирає змінене завдання належним чином. До речі, я не був усвідомлений ':як "розсувне вікно" - цікаво.
ngn

Ви, здається, добре знайомі з k. Якщо ви коли-небудь відчуваєте, як обговорювати речі з програмуванням векторного програмування з однодумцями або просто спостерігати, як решта нас сперечаються - у нас є ця чатна кімната . Більшість стендів про APL, але k і J теж на тему.
ngn



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

Додатково, 99 байт

Натхненний @Neil. Цифри відповідності Regex лише із "попередньою цифрою" непарні ". Matchesє автоматичною змінною .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s

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 не бачить масив 0 і 1, що є результатом oяк логічний масив, замість цього приймає їх як числові індекси та індекси на позиції 1та end.


Я думаю, ви можете використовувати !Uзамість цього 48-. Здається, транспонирование тут не шкодить. oдля doubleвведення просто mod(...,2), тому вихід є double. Приємний NaNвхідний трюк! Якщо це призначене для вирішення сторонніх результатів в STDOUT, у Денніса була ідея і, ймовірно, це скоро виправлять
Луїс Мендо

!Uзамість48-
Джузеппе

@LuisMendo welp, ти побив мене до удару!
Джузеппе

@Giuseppe :-D :-D
Луїс Мендо

Дякую обом, відредаговано. @LuisMendo Коли oтоді виводиться логічний масив - чи ні? (Мушу зізнатися, я ніколи насправді не заглядав у числову систему типу MATLAB.) І так, я думав, що NaNвдасться зробити гарний дозорний, оскільки це навряд чи буде фактичним вкладом у будь-якому місці, але добре знати, що він не знадобиться довше !
sundar

2

K (нг / к) , 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

Спробуйте тут .

Цього разу вона працює без цифр! Введення - це список символів.


19 байт , включаючи перехід на Japt v2. Не задоволений масивом у xфункції. Пінг мені в чаті, якщо у вас є питання.
Shaggy

Зачекайте, щойно помітили, що це взагалі не буде працювати, якщо вхід не містить цифр.
Кудлатий

Крім того, де джерело для v2.0a0, @Shaggy? Я не можу знайти його в репо.
LegionMammal978


Якщо ви пропустили це в чаті, я знизив це на 12 байт .
Shaggy

2

05AB1E , 12 9 байт

Заощаджує 1 байт над наївним методом, використовуючи трюк паритету дилнан.
Збережений 3 байти завдяки містеру 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

Хм, було б þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·або þÀsþ€ÉÏSO·пройти всі тестові випадки для -2 байт?
Містер Xcoder

@ Mr.Xcoder: Ага, так. Приємно! Ми навіть можемо зробити þDÁ€ÉÏSO·для -3 :)
Емінья

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]).

Видаліть цифри, які не відповідають непарній цифрі.

.
$*

Перетворити в одинарне.

.
..

Подвоюйте їх.

.

Візьміть суму.


Боюся, результат буде невірним, якщо остання цифра не буде непарною
маззи

1
@mazzy Коли ви говорите останню цифру, ви маєте на увазі до чи після копіювання першої цифри до кінця?
Ніл

'до кінця'. крок "Додавання дубліката першої цифри" копіює до кінця? добре. круто. Дякую
mazzy


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

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)

Спробуйте в Інтернеті!

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


n-0можна+n
ов

Ласкаво просимо до PPCG!
Conor O'Brien

1

R , 58 байт

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

Спробуйте в Інтернеті!

  • використовуючи трюк паритету Ділнана
  • -8 байт, приймаючи вектор символів замість рядків
  • -3 байти завдяки @Giuseppe

67 байт, якщо ви не заперечуєте над arrayрезультатами.
Джузеппе

1
Хм, насправді ви не можете використовувати крапковий продукт через порожній масив, xxxтак що це 68 байт, використовуючи зміни в індексації aдля створення y.
Джузеппе

@Giuseppe: модифіковано, дякую :)
digEmAll

@Giuseppe: Я прошу вашу думку, оскільки ви мудріший гольфіст з коду ... з коментарів, здається, ми можемо використовувати вектор символів, в цьому випадку можливий 61 байт: Спробуйте в Інтернеті! що ти думаєш ?
digEmAll

використовувати strtoiзамість as.double, але так, це повинно бути добре.
Джузеппе



0

C Різкий 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;}}

Безголівки:

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

0

Стакс , 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

Очікує введення як масив символів. Caveat: Завдяки використанню зсуву бітів, вихід має верхню межу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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.