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


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.