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


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.