Простий цілочисельний калькулятор операцій


28

Запропонуйте простий калькулятор сценаріїв з цілої операцією.

Концепція

Акумулятор починається з 0 і на ньому виконуються операції. В кінці програми виведіть значення акумулятора.

Операції:

  • +додає 1до акумулятора
  • -віднімає 1від акумулятора
  • * помножує акумулятор на 2
  • / ділить акумулятор на 2

Зразок сценарію

Вхід ++**--/повинен дати вихід 3.

Приклад реалізації

def calc(s)
    i = 0
    s.chars.each do |o|
        case o
            when '+'
                i += 1
            when '-'
                i -= 1
            when '*'
                i *= 2
            when '/'
                i /= 2
        end
    end
    return i
end

Правила

  • Це , тому найнижча відповідь у байтах виграє, але не вибирається.
  • Заохочуються творчі реалізації.
  • Стандартні лазівки заборонені.
  • Ви отримуєте програму за допомогою stdin або аргументів, а відповідь можна виводити через повернене значення або stdout.
  • Весело.
  • Ділення скорочується вниз, тому що це ціле ділення.
  • Програма -/повертається -1.

Тестові справи

*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17 
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342

2
Отже ... це не суворо ціле число, оскільки /може дати нецілі числа.
— Conor O'Brien

2
Тоді слід чітко вказати це.
— Conor O'Brien

5
Що слід -/повернути?
— Денніс

4
Не можу не помітити, що фрагмент коду, розміщений на домашній сторінці іржі-язика, вирішує цю проблему.
— Цвай

4
Будь ласка, додайте більше тестових випадків.
— Мартін Ендер

Відповіді:


28

Python 2, 48 байт

i=0
for c in input():exec"i=i%s2&-2"%c
print i/2

Чи має +2, -2, *2або /2. Поступаючи +2і -2замість того , +1і -1ми працюємо в здвоєних одиницях, тому кінцеві потреби вихідних , щоб зменшити вдвічі. За винятком того, що поділ підлоги /тепер має округлювати до кратного 2, що робиться за допомогою &-2.


Це геніально! Якщо ви хочете розмістити його самостійно, порт CJam, це в даний час є головним завданням: 0q{2\~-2&}/2/( 2\~зрівняється оператор з другим операндом 2, -2&є побітним І, 2/є остаточним поділом на два. q{...}/Це передбачення над входом і 0є лише початковим значення.)
— Мартін Ендер

Ви можете опублікувати це, я не знаю, CJam.
— xnor

Дійсно розумний! Передано ES6, це легко перевершить мою відповідь
— edc65

Блискуче використання пітона. Дізналися з цього чогось нового.
— Якобр365

12

Haskell, 51 байт

x#'+'=x+1
x#'-'=x-1
x#'*'=x*2
x#_=div x 2 
foldl(#)0

Приклад використання: foldl(#)0 $ "++**--/"-> 3.


12

Желе , 18 17 байт

‘

’

:2
Ḥ
O0;ṛĿ/

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

Як це працює

Перші шість рядків визначають допоміжні зв’язки з індексами від 1 до 6 ; вони збільшуються, нічого не роблять, декремент, нічого не роблять, наполовину (настил) і подвоюють.

Основне посилання - O0;ṛĿ/- перетворює вхідні символи в їхні кодові точки ( O), попередньо додає 0 (початкове значення) до масиву кодових точок 0;, а потім зменшує згенерований масив наступним чином.

Початкове значення - це перший елемент масиву, тобто попередньо передбачений 0 . Швидке посилання ṛĿвикликається для кожного наступного елемента в масиві, останнє повернене значення - як лівий аргумент, а поточний елемент - як правий. Він перевіряє правильний аргумент ( ṛ) і оцінює зв’язок з цим індексом монадично ( Ŀ), застосовуючи таким чином бажану операцію.


10
Це схоже на відповідь желе з найбільш новими рядками
— Conor O'Brien

10

Python 2, 54 байти

i=0
for c in input():exec"i=i"+c+`~ord(c)%5%3`
print i

Введення приймається як літеральний рядок. ~ord(c)%5%3відображає операторів на відповідні праві операнди.

Раніше я використовував, hash(c)%55%3який не давав стійких результатів між різними версіями Python. Це спонукало мене вивчити інші формули.


здається, не працює ...
— Зруйнований лимон

55,3 та 65,4 - два найкоротші для подвійного мода хешу в python 2
— Jonathan Allan

@DestructibleWatermelon робить для мене: ideone
— Джонатан Аллан

Я думаю hash, що версія Python специфічна - ideone використовує 2.7.10, що дає [1, 1, 2, 2]чотири відображення, тоді як локально на 2.7.12 я отримую[2, 0, 1, 0]
— Sp3000

1
він працює на ideone, але не на моїх комп'ютерах python. Можливо, залежно від версії, у такому разі слід зазначити версію EDIT: ninja'd: /
— Destructible Lemon

10

SILOS , 133 211 байт

:s
def : lbl G GOTO
readIO
i-46
if i a
i+2
if i b
i+2
if i c
i+1
if i d
G e
:a
G v
:p
a-1
a/2
G o
:v
a+1
if a p
a-1
j=a
j/2
k=j
k*2
k-a
a/2
if k t
G o
:t
a-1
:o
G s
:b
a-1
G s
:c
a+1
G s
:d
a*2
G s
:e
printInt a

Бере коди операторів ASCII.

Спробуйте в Інтернеті з тестовими кейсами:
-/
++**--/
*///*-*+-+


це loadLine golfer?
— Rohan Jhunjhunwala

ОП уточнили; -/має повернути -1 , а не 0 .
— Денніс

@Dennis виправлено. Додано багато байтів, хоча: /
— betseg

9

Машина Тьюрінга - 23 штати (684 байти)

Спробуйте тут - постійна посилання

0 * * r 0
0 _ . l 1
1 * * l 1
1 _ * l 2
2 * 0 r 3
3 _ * r 3
3 + _ l +
3 - _ l -
3 x _ l x
3 / _ l /
+ _ * l +
+ * * * 4
4 - * l 5
4 _ 1 r 6
4 0 1 l 7
4 1 0 l 4
- _ * l -
- * * * 5
5 - * l 4
5 _ * r 8
5 0 1 l 5
5 1 0 l 7
x * * l x
x 1 0 l 9
x 0 0 l a
9 _ 1 r 6
9 1 1 l 9
9 0 1 l a
a _ _ r 6
a 1 0 l 9
a 0 0 l a
/ _ * l /
/ * * l b
b * * l b
b _ * r c
c 0 0 r d
c 1 0 r e
d * * l 7 
d 0 0 r d
d 1 0 r e
e _ * l 7
e - * l 4
e 0 1 r d
e 1 1 r e
8 * * r 8
8 - _ r 3
8 _ - r 3
7 * * l 7
7 _ * r f
f 0 _ r f
f 1 * r 6
f * _ l g
g * 0 r 6
6 * * r 6
6 _ * r 3
3 . _ l h
h _ * l h
h - _ l i
h * * l halt
i * * l i
i _ - r halt

Введення не повинно містити жодного "*", оскільки це спеціальний символ у машинному коді Тьюрінга. Використовуйте замість "x". Виводить відповідь у двійковій формі.

Невиражений код

init2 * * r init2
init2 _ . l init0
init0 * * l init0
init0 _ * l init1
init1 * 0 r readop
readop _ * r readop
readop + _ l +
readop - _ l -
readop x _ l x
readop / _ l /
+ _ * l +
+ * * * inc
inc - * l dec
inc _ 1 r return
inc 0 1 l zero
inc 1 0 l inc
- _ * l -
- * * * dec
dec - * l inc
dec _ * r neg
dec 0 1 l dec
dec 1 0 l zero
x * * l x
x 1 0 l x1
x 0 0 l x0
x1 _ 1 r return
x1 1 1 l x1
x1 0 1 l x0
x0 _ _ r return
x0 1 0 l x1
x0 0 0 l x0
/ _ * l /
/ * * l //
// * * l //
// _ * r div
div 0 0 r div0
div 1 0 r div1
div0 * * l zero 
div0 0 0 r div0
div0 1 0 r div1
div1 _ * l zero
div1 - * l inc
div1 0 1 r div0
div1 1 1 r div1
neg * * r neg
neg - _ r readop
neg _ - r readop
zero * * l zero
zero _ * r zero1
zero1 0 _ r zero1
zero1 1 * r return
zero1 * _ l zero2
zero2 * 0 r return
return * * r return
return _ * r readop
readop . _ l fin
fin _ * l fin
fin - _ l min
fin * * l halt
min * * l min
min _ - r halt

Пояснення станів:

Ініціалізація:
ці стани відвідуються один раз на початку кожного запуску, починаючи з init2

  • init2: Просуньтеся вправо і поставте "." Таким чином ТМ знає, коли зупинитись. Змініть на "init0".
  • init0: переміщайте всю спинку вліво, поки голова не прочитає пробіл. Потім перемістіть одну клітинку вліво. Змініть на "init1".
  • init1: Поставте нуль і перемістіть одну клітинку вправо і змініть на "readop".

Інструкції з читання:
Ці стани будуть відвідуватися кілька разів протягом усієї програми

  • readop: рухається повністю вправо, доки він не прочитає оператора або '.'. Якщо він потрапляє на оператора, змініть його на відповідний стан (+, -, x, /). Якщо він потрапляє на ".", Перемніть на стан "fin".

  • return: Повертає голову в порожній простір між загальною кількістю операторів та операторами. Потім змінюється на "readop".

Операції:
Ці операції виконують фактичну брудну роботу

  • +: Перемістіться ліворуч, поки голова не прочитає будь-який символ, який не пробігає. Якщо цей символ є "-", перемістіть ліворуч та змініть на "dec". В іншому випадку перейдіть на "inc".

  • -: Подібно до '+', за винятком зміни на 'inc', якщо в іншому випадку є '-' та 'dec'.

  • inc: Якщо цифра під головою дорівнює 0 (або пробіл), змініть її на 1 і змініть на 'zero'. Якщо цифра дорівнює 1, змініть її на 0, а потім повторіть наступну цифру.

  • dec: Подібно до inc, за винятком 1 переходить до 0, 0 - до 1, і якщо голова читає пробіл, змініть на 'neg'.

  • x, x0, x1: Переміщення номер один ліворуч. Змініть на "повернення".

  • /, //, div, div0, div1: пересуньтеся вправо від числа, а потім перемістіть біт вправо. Якщо є "-", перейдіть на "inc". Це імітує округлення від'ємних чисел. В іншому випадку змініть на "нуль"

  • neg: Поставте число "-" після числа, а потім змініть на "readop"

  • zero, zero1, zero2: Видаліть провідні нулі та перейдіть на 'readop'

Очищення: робить вихідний показ презентабельним

  • fin, min: За необхідності перемістіть "-" перед цифрою. Зупинка.

1
Думав, що читати цей код було дуже круто. Тож спасибі за те, що полегшив мені день.
— Jacobr365

8

Perl 6 , 53  52 байти

{([Ro] %(<+ - * />Z=>*+1,*-1,* *2,*div 2){.comb})(0)}

{[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}

Пояснення:

# bare block lambda that has one implicit parameter 「$_」
{
  (
    # reduce the code refs using ring operator 「∘」 in reverse 「R」
    [R[o]]

      # produce a hash from:
      %(

        # list of pairs of "operator" to code ref
        # ( similar to 「'+' => { $^a + 1 }」 )

          # keys
          < + - * / >

        # keys and values joined using infix zip operator 「Z」
        # combined with the infix Pair constructor operator 「=>」
        Z[=>]

          # values (Whatever lambdas)
          * + 1,
          * - 1,
          * × 2, # same as 「* * 2」
          * div 2,

      ){

        # split the block's argument into chars
        # and use them as keys to the hash
        # which will result in a list of code refs
        .comb

      }

  # call composed code ref with 0
  )(0)
}

Використання:

my $input = '++**--/'
my $output = {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}.( $input );
say $output; # 3
say $output.^name; # Int


6

05AB1E , 20 байт

Дякуємо Enigma за виправлення -/помилки!

Для 16 байт , якщо це не було ціле розподіл: Î"+-*/""><·;"‡.V.

Î…+-*"><·"‡'/"2÷":.V

Пояснення:

Î                      # Push 0, which is our starting variable, and input
 …+-*                  # Push the string "+-*"
     "><·"             # Push the string "><·"
          ‡            # Transliterate. The following changes:
                           "+" -> ">"
                           "-" -> "<"
                           "*" -> "·"
           '/"2÷":     # Replace "/" by "2÷"
                  .V   # Evaluate the code as 05AB1E code...
                           '>' is increment by 1
                           '<' is decrement by 1
                           '·' is multiply by 2
                           '2÷' is integer divide by two
                       # Implicitly output the result

Використовує кодування CP-1252 . Спробуйте в Інтернеті!


ОП уточнили; -/має повернути -1 , а не 0 .
— Денніс

Питання поділу від’ємного числа можна виправити Î…+-*"><·"‡'/"2÷":.Vза тим самим підрахунком байтів.
— Емінья

@Dennis Виправлена ​​проблема.
— Аднан

@Emigna Спасибі :)
— Аднан

5

JavaScript ES6, 80 68 байт

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}‌​[o],0)

Збережено колосальних 12 байт завдяки Нілу!


Друга відповідь буде читабельнішою, якби ви видалили "c"+і написали "c+1 c-1 c*2 c/2|0".splitі т.д.
— Ніл

Для першої відповіді, чому б не написати o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)], або я думаю, що ви можете продовжити, щоб зберегти подальший байт o=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o].
— Ніл

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0)можливо, вийде ще коротше, але я втратив рахунок ...
— Ніл

@Neil Ага, так, я забув про це
— Conor O'Brien

1
Ви якось потрапили до нульової ширини символів між }і [o], так що це насправді лише 66 байт. Також ОП уточнили; -/має повернути -1 , а не 0 .
— Денніс

5

Рубі, 48 44 42 + 1 = 43 байти

+1 байт для -nпрапора Здійснює введення даних STDIN.

i=0
gsub(/./){i=i.send$&,"+-"[$&]?1:2}
p i

Дивіться це на ideone (використовується, $_оскільки ideone не приймає прапор командного рядка): http://ideone.com/3udQ3H



4

Python 2, 58 56 байт

-2 байти завдяки @Lynn

r=0
for c in input():exec'r=r'+c+`2-ord(c)%11%3`
print r

Ордіналов персонажів +-*/є по 43,45,42,47модулю 11 це по 10,1,9,3модулю 3 ті 1,1,0,0, 2 менше тих , які 1,1,2,2дають суми нам потрібно для кожної операції: r=r+1, r=r-1, r=r*2, іr=r/2


Попередній:

r=0
for c in input():exec'r=r'+c+`(ord(c)%5==2)+1`
print r

Як щодо 2-ord(c)%11%3?
— Лінн

@Lynn Ну я візьму це, якщо з вами все гаразд? (але насправді думаю, що цього достатньо для зміни, яку ви можете опублікувати)
— Джонатан Аллан

2
Вперед :) ----
— Лінн

4

Математика, 83 73 70 байт

10 байт збережено завдяки @MartinEnder .

(#/*##2&@@#/.Thread[{"+","-","*","/"}->{#+1&,#-1&,2#&,⌊#/2⌋&}])@0&

Анонімна функція. Приймає список символів як вхідний і повертає число як вихід. Пропозиції з гольфу вітаються.



4

C #, 87 81 байт

int f(string s){int i=0;foreach(var c in s)i=c<43?i*2:c<46?i+44-c:i>>1;return i;}

Безголівки:

int f(string s)
{
    int i = 0;

    foreach (var c in s)
        i = c < 43 ? i * 2
          : c < 46 ? i + 44 - c
          : i >> 1;

    return i;
}

Введення вважається дійсним. Ділення на два здійснюється зміщенням правого біта, тому що регулярне ділення завжди кругляється до нуля, а бітове зміщення завжди - вниз. Збільшення та зменшення корисно використовують 1 відстань між кодами ASCII для +та -.


Якась любов до нового синтаксису C # 6 та агрегатного методу Linq? int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);(65 байт)
— Кирило Гандон

@ CyrilGandon, наскільки я знаю, що потрібно було б включити "використання System.Linq;", що зробить його на 19 довше і поставить його на 84 байти. Тому я цього не зробив.
— Сцефео

4

Javascript (ES6), 57 байт (масив) / 60 байт (ціле число)

Повернення масиву всіх проміжних результатів:

o=>[...o].map(c=>x=[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],x=0)

Наприклад, вихід для "++**--/"буде [1, 2, 4, 8, 7, 6, 3].

Повернення лише остаточного результату:

o=>[...o].reduce((x,c)=>[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],0)

Як це працює

Обидва рішення засновані на одній ідеї: використання ідеальної хеш-функції eval(2+c+3)&3для відображення різних символів оператора cв [0, 3].

 operator | eval(2+c+3)  | eval(2+c+3)&3
----------+--------------+---------------
    +     |  2+3 = 5     |    5 & 3 = 1
    -     |  2-3 = -1    |   -1 & 3 = 3
    *     |  2*3 = 6     |    6 & 3 = 2
    /     |  2/3 ~= 0.67 | 0.67 & 3 = 0

3

JavaScript (ES6), 57

a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

Примітка: початкове значення для акумулятора - це програмний рядок, за допомогою бітових операцій (~, >>, <<, |) воно перетворюється в 0 при першому використанні.

Як бічна примітка, розумна відповідь @xnor набере 40 перенесених у javascript:

a=>[...a].map(c=>a=eval(~~a+c+2))&&a>>1

(якщо вам це подобається, голосуйте за нього)

Тест

f=a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

function update() {
  O.textContent = f(I.value);
}

update()
<input value='++**--/' id=I oninput='update()'><pre id=O></pre>


3

Java, 77 байт

int f(String s){return s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);}

Використовує java 8 потоків.


1
Приємна відповідь і ласкаво просимо на сайт! Я нічого про Java не знаю, але ви можете змінити , r >> 1щоб r>>1і зберегти 2 байти?
— DJMcMayhem

Ви абсолютно правильні, дякую @DJMcMayhem
— primodemus

1
Дивовижно, радий, що можу допомогти! Ще одна примітка, я рахую 77 байт. Чи траплялось вам включити новий рядок у свій кількість байтів? Ви можете зняти ще один байт, оскільки це не потрібно.
— DJMcMayhem

Виправте знову @DJMcMayhem, мабуть, wc рахує нульовий закінчуючий байт чи щось таке
— primodemus

1
як ви використовуєте java8, чому б не визначити функцію за допомогою лямбда, s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);це дасть вам 56 байт
— user902383

3

GNU sed, 65 59 57 байт

Редагувати: 2 байти коротше завдяки коментарям Toby Speight

s/[+-]/1&/g
s/*/2&/g
s:/:d0>@2&:g
s/.*/dc -e"0[1-]s@&p"/e

Виконати:

sed -f simple_calculator.sed <<< "*///*-*+-+"

Вихід:

-1

sedСценарій готує вхід для dcвиклику оболонки в кінці кінців, останній прийом вхід в зворотної польської записи . При поділі, якщо число від'ємне ( d0>), викликається [1-]команда decrement, що зберігається в регістрі @. Приклад перетворення: + - * /-> 1+ 1- 2* d0>@2/.


Вам не потрібні лапки навколо аргументу на постійний струм, якщо немає пробілів і файлів, що відповідають [1-]шаблону ...
— Toby Speight

@TobySpeight На мій погляд , я переключився сенс sз S. Я забув, що він не замінює стек реєстру, він натискає на нього, маючи протилежний ефект від того, що я хотів (оскільки я використовував його для кожного /). Цитати все ще потрібні, оскільки у вас є /символи, що рядок інтерпретується як шлях до файлу :) Я поголив на 1 байт більше, видаливши пробіл після -e.
— seshoumara

1
DC не буде інтерпретувати аргумент -eяк ім'я файлу, тому вам не потрібні цитати для цього /- спробуйте! Я думаю, що для коду-гольфу доцільно вимагати, щоб поточний робочий каталог не містив файлів, що починаються з 01s@або 0-s@.
— Toby Speight

@TobySpeight Ви мали рацію -eщодо /, проте цитати все ще потрібні, як я щойно бачив. >Інтерпретується безпосередньо оболонки в якості оператора перенаправлення Я думаю , що , так як я отримав цю помилку:cannot create @2/d0: Directory nonexistent
— seshoumara

А, так, я не вважав це >. Вам потрібні цитати, зрештою. Вибачення за (спробу) ввести в оману! І хоча додавання зворотної косої риси виглядає як один символ, її потрібно s///замінити вдвічі, замість цього ніякої вигоди немає ...
— Toby Speight

3

PHP, 75 байт

Тут використовується модифікована версія відповіді Йорга Гюльсермана .

eval(preg_replace('~.~','$s=($s\0(2-ord("\0")%11%3))|0;',$argv[1]));echo$s;

Він сильно покладається на підстановку рядків, використовуючи простий регулярний вираз ( ~.~).

Змінній $sповторно присвоюється нове значення для кожного символу. Наприкінці він виводить результат.


Примітка . Це призначено для виконання за допомогою -rпрапора.


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

Або спробуйте: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

Відмінності:

  • Замість цього echo$sя використовую sprintf($s). Обидва виконують однакову дію на числа. Оскільки це лише для тестування, це добре.
  • У випадку, якщо аргумент не пройдений, він запускається так, як якщо б ви передали ++*+як перший аргумент, який повинен показувати 5.

Так! eМодифікатор повертається! : D
— Тіт

@Titus Я не розумію. Ви можете трохи допрацювати?
— Ісмаїл Мігель

PHP до версії 7 мав модифікатор шаблонуe , який був замінений preg_replace_callbackі може бути зловживаний ... але це не зовсім так.
— Тіт

@Titus Цей патерн-модифікатор використовувався для того, щоб сказати, що вихід буде фактичним PHP-кодом, і намагатися підтримувати правильний синтаксис. Це тут, не використовує його, але замінює кожен символ на фрагмент коду для виконання, незалежно від його синтаксису. Погане введення спричинить серйозні проблеми із безпекою.
— Ісмаїл Мігель

Я знаю. Але це нагадує.
— Тіт

2

Пакет, 61 байт

@set n=
@for %%a in (%*)do @set/an=n%%a2^&-2
@cmd/cset/an/2

Переклад кселентної відповіді Python @ xnor.


2

Пайк, 24 22 байти

\*\}:\/\e:\+\h:\-\t:0E

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

Або 12 байт (неконкурентоспроможний)

~:"ht}e".:0E

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

Додати translateвузол - в основному кілька разів знайти і замінити.

~:           -   "+-*/"
        .:   -  input.translate(^, V)
  "ht}e"     -   "ht}e"
          0E - eval(^, stack=0)

2

PHP, 104 102 82 байт

Перша версія з eval:

$i=0;while($c<9999)eval('$i'.['+'=>'++','-'=>'--','*'=>'*=2','/'=>'>>=1'][$argv[1]{$c++}].';');echo$i;

Друга версія з потрійними операторами:

while($o=ord($argv[1]{$c++}))$i=$o<43?$i*2:($o<44?$i+1:($o<46?$i-1:$i>>1));echo$i;

Приймає рядок введення як перший аргумент з командного рядка.

Цей "лише" працює для вхідних рядків, менших за 10 000 символів - що має бути достатньо. Протестований у всіх тестових випадках, на жаль, не вдається заощадити на ініціалізації на початку. Друга версія працює з рядками будь-якої довжини і без ініціалізації. :-)

Основним елементом є функція eval, яка маніпулює $iна основі карти арифметичних операцій, які є досить простими, за винятком поділу. PHP повертає float при використанні /і intdivмає занадто багато байтів, тому ми робимо правильний зсув .

Оновлення

  1. Збережено 2 байти шляхом скорочення $i=$i>>1до $i>>=1цілого поділу.
  2. Викинув eval на користь тернарних операторів.

2

Пітон 3, 98 66 60 байт

Спасибі Tukkax!

Не настільки гофрований, як інша відповідь, але я не можу конкурувати з ними без плагіату.

i=0
for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4]
print(i)

Також у мене є рекурсивний лямбда-розчин

73 67 байт (покращено!)

s=lambda x,z=0:s(x[1:],z+[1,-z//2,-1,z][ord(x[0])%23%4])if x else z

Застосовуючи частину вашого рекурсивного рішення процедурної версії: 60 байт: i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i). (звичайно, не відформатовано належним чином). Також я думаю, ви повинні згадати, що ви використовуєте Python3. У Python2, input()оцінив би int(raw_input()).
— Yytsi

@TuukkaX не працює для z = 0 ( +-робить 1)
— Зруйнований лимон

о так, моя помилка.
— Yytsi

1
Додайте назву Python3, будь ласка.
— Yytsi

2

R, 201 байт

Гольф

p=.Primitive;"-"="+"=function(x)p("+")(x,1);body(`-`)[[1]]=p("-");"*"="/"=function(x)p("*")(x,2);body(`/`)[[1]]=p("%/%");Reduce(function(f, ...)f(...),rev(mget(strsplit(scan(stdin(),""),"")[[1]])),0,T)

Прокоментував

p = .Primitive                       # Redefine
"-" = "+" = function(x)p("+")(x,1)   # Define - and +
body(`-`)[[1]] = p("-")              # Change the body, what we do to save a byte
"*" = "/" = function(x)p("*")(x,2)   # Same as above
body(`/`)[[1]] = p("%/%")            # Same as above
Reduce(function(f, ...)f(...),       # Function wrapper to evaluate list of func.  
  rev(mget(strsplit(scan(stdin(),""),"")[[1]])), # Strsplit input into list of functions
  init = 0,                                      # Starting Arg = 1
  right = T)                                     # Right to left = True 

Стратегія полягає в удосконаленні +, -, %операторів. Розділіть рядок, потім розберіть рядок на довгий список функцій, які будуть подаватися в Reduce()'sакумулятор.

Більше не можна було бити в гольф. Якщо хтось може взяти b=body<-на роботу, може бути кілька байтів економії (уточнити кожну функцію bпісля "-"="+"="/"="*"). Спочатку намагалися підмінити та розібрати eval, але порядок операцій та дужок був жахливим.


Це рік потому, але мені вдалося отримати його 10 байт шляхом заміни вашого підходу трохи - ви можете залишити 8 байт, видаляючи простір між f, ...у визначенні Reduceфункції і позбутися від stdin()в , scanале я просто спробував наївним підхід, який скинув ще два байти, визначивши функції трохи інакше. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/…
— Джузеппе

1

Lex + C, 78 , 74 , 73 байт

Перший персонаж - пробіл.

 c;F(){yylex(c=0);return c;}
%%
\+ c++;
- c--;
\* c*=2;
\/ c=floor(c/2.);

Читає з stdin, повертає результат.

Компілювати з lex golfed.l && cc lex.yy.c main.c -lm -lflосновним тестом:

int main() { printf("%d\n", F()); }

1

Javascript (ES5), 127 байт

function(b){for(a=c=0;a<b.length;++a)switch(b[a]){case"+":++c;break;case"-":--c;break;case"*":c*=2;break;case"/":c/=2}return c}

Безголівки:

function c(a){
  c=0;
  for(var i=0;i<a.length;++i){
    switch(a[i]){
      case "+":++c;break;
      case "-":--c;break;
      case "*":c*=2;break;
      case "/":c/=2;break;
    }
  }
  return c;
}

1

Pyth, 23 байти

FNQ=Z.v%".&%sZ2_2"N;/Z2

Повна програма, яка приймає дані як рядок і друкує результат.

Це порт відповіді Python @ xnor .

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

Як це працює

FNQ=Z.v%".&%sZ2_2"N;/Z2   Program. Input: Q. Z initialised as 0
FNQ                       For. For N in Q:
        ".&%sZ2_2"         String. Literal string ".&%sZ2_2"
       %          N        String format. Replace %s with the current operator N
           %sZ2            Operator. Yield Z*2, Z//2, Z+2, Z-2 as appropriate
         .&    _2          Bitwise and. Result of above & -2
     .v                    Evaluate. Yield the result of the expression
   =Z                      Assignment. Assign result of above to Z
                   ;      End. End for loop
                    /Z2   Integer division. Yield Z//2
                          Print. Print the above implicitly 

1
Перетворення Python в Pyth - це здебільшого погана ідея. u@[yGhG0tG0/G2)CHQ019 байт
— Якубе

@Jakube Спасибі - я дуже новачок у Pyth, тому будь-які поради цінуються. Сміливо публікуйте це як окрему відповідь, оскільки це інший підхід.
— TheBikingViking

1

PHP, 79 байт

<?$i=0;switch($_POST['a']){case"+":$i+1;case"-":$i-1;case"/":$i/2;case"*":$i*2}

2
Включіть у своєму заголовку рахунок рахунку, видаліть непотрібні пробіли та використовуйте 1-літерні імена змінних.
— TuxCrafting

Це навіть гольф ?! :-D
— YetiCGN

@ TùxCräftîñg Я це зробив.
— Вінні Пух

Ви ділите і множите на 1; вам потрібно розділити і помножити на2
— TuxCrafting

@ TùxCräftîñg Я це зробив.
— Вінні Пух
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.