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

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

правила

  • Это , поэтому младший ответ в байтах выигрывает, но не выбирается.
  • Творческие реализации приветствуются.
  • Стандартные лазейки запрещены.
  • Вы получаете программу через стандартный ввод или аргументы и можете вывести ответ через возвращаемое значение или стандартный вывод.
  • Повеселись.
  • Деление сокращается, потому что это целочисленное деление.
  • Программа -/возвращается -1.

Контрольные примеры

*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17 
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342
dkudriavtsev
источник
2
Так что ... это не строго целое число, так как /может давать нецелые числа.
Конор О'Брайен
2
Тогда вы должны указать это явно.
Конор О'Брайен,
5
Что должно -/вернуться?
Денис
4
Я не могу не заметить, что фрагмент кода, размещенный на домашней странице rust-lang, решает эту проблему.
Цвей
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.

XNOR
источник
Это великолепно! Если вы хотите опубликовать его самостоятельно, порт CJam этого будет в настоящее время вести вызов: 0q{2\~-2&}/2/( 2\~обнуляет оператор со вторым операндом 2, -2&является побитовым AND, 2/является окончательным делением на два. q{...}/Является foreach над входом и 0является только начальным значение.)
Мартин Эндер
Вы можете опубликовать это, я не знаю CJam.
xnor
Действительно умный! Портированный на ES6, это легко превзойдет мой ответ
edc65
Блестящее использование питона. Узнал что-то новое из этого.
Jacobr365
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
Это похоже на желейный ответ с большинством новых строк
Конор О'Брайен
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. Это побудило меня изучить другие формулы.

xsot
источник
не похоже на работу ...
Разрушаемый лимон
55,3 и 65,4 - два самых коротких для двойного мода хэша в питоне 2
Джонатан Аллан
@DestructibleWatermelon делает для меня: ideone
Джонатан Аллан
Я думаю, что это hashзависит от версии Python - Ideone использует 2.7.10, который дает [1, 1, 2, 2]в качестве четырех отображений, тогда как локально на 2.7.12 я получаю[2, 0, 1, 0]
Sp3000
1
это работает на ideone, но не на моих компьютерах python. Вероятно, зависит от версии, в этом случае следует указать версию. РЕДАКТИРОВАТЬ: ninja'd: /
Разрушаемый Лимон
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 коды операторов.

Попробуйте онлайн с тестовыми примерами:
-/
++**--/
*///*-*+-+

betseg
источник
loadLine - гольф?
Рохан Джунджхунвала
ОП уточнил; -/должен вернуть -1 , а не 0 .
Деннис
@ Денис исправлен. Хотя добавлено много байтов: /
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

Входные данные не должны содержать никаких «*», так как это специальный символ в машинном коде Тьюринга. Вместо этого используйте «х». Выводит ответ в двоичном виде.

Необъяснимый код

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 и измените на «ноль». Если цифра равна 1, измените ее на 0, затем повторите следующую цифру.

  • dec: аналогично inc, за исключением того, что 1 переходит в 0, 0 переходит в 1, а если заголовок считывает пробел, изменится на 'neg'.

  • x, x0, x1: сдвиг влево на номер один. Изменить на «возврат».

  • /, //, div, div0, div1: переместиться полностью вправо от числа, затем сдвинуть бит на единицу вправо. Если есть «-», измените на «inc». Это моделирует округление отрицательных чисел. В противном случае, изменить на «ноль»

  • neg: поместите «-» после числа, затем измените на «readop»

  • ноль, ноль1, ноль2: удалить ведущие нули и изменить на «readop»

Очистка: делает вывод презентабельным

  • fin, min: при необходимости передвиньте «-» перед номером. Halt.
KoreanwGlasses
источник
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
Брэд Гилберт b2gills
источник
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тем же количеством байтов.
Эмигна
@ Денис Исправил проблему.
Аднан
@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)может получиться еще короче, но я потерял счет ...
Нил
@ Нил Ах, да, я забыл об этом
Конор О'Брайен
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

Иордания
источник
5

PHP 76 байт

for(;$c=$argv[1][$n++];)eval('$s=floor($s'.$c.(2-ord($c)%11%3).');');echo$s;
Йорг Хюльсерманн
источник
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?
Линн
@ Линн Ну, я возьму это, если с тобой все в порядке? (но на самом деле думаю, что достаточно изменений, которые вы могли бы опубликовать)
Джонатан Аллан
2
Продолжай :) ----
Линн
4

Mathematica, 83 73 70 байт

10 байтов сохранено благодаря @MartinEnder .

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

Анонимная функция. Принимает список символов в качестве ввода и возвращает число в качестве вывода. Предложения по игре в гольф приветствуются.

LegionMammal978
источник
4

SILOS , 175 164 байта

loadLine
a=256
o=get a
lbla
a+1
o-42
p=o
p-1
p/p
p-1
r-p
s=o
s-3
s/s
s-1
r+s
m=o
m/m
m-2
m|
r*m
t=r
t%2
d=o
d-5
d/d
d-1
t*d
d-1
d|
r-t
r/d
o=get a
if o a
printInt r

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

Вменяемый метод ввода. Правильное целочисленное деление (округление к бесконечности).

Дрянная Монахиня
источник
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;}

Ungolfed:

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 для +и -.

Scepheo
источник
Кто-то любит новый синтаксис 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 должен будет включать «using 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
Arnauld
источник
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>

edc65
источник
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 потоков.

primodemus
источник
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 байта короче благодаря комментариям Тоби Спейт

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-]уменьшения, сохраненная в регистре @. Пример конвертации: + - * /-> 1+ 1- 2* d0>@2/.

seshoumara
источник
Вам не нужны кавычки вокруг аргумента dc, если нет пробелов и нет файлов, соответствующих [1-]шаблону ...
Тоби Спейт
@TobySpeight В своем уме я переключил значение sс S. Я забыл, что он не заменяет стек реестра, он выдвигает на него, оказывая противоположный эффект от того, что я хотел (так как я использовал его для каждого /). Кавычки все еще нужны, потому что у вас есть /символы, которые делают строку интерпретированной как путь к файлу :) Я побрил еще 1 байт, удалив пробел после -e.
Сешумара
1
dc не будет интерпретировать аргумент -eкак имя файла, поэтому вам не нужны кавычки для /- попробуйте! Я думаю, что для кода-гольфа разумно требовать, чтобы текущий рабочий каталог не содержал никаких файлов, начинающихся с 01s@или 0-s@.
Тоби Спейт
@TobySpeight вы были правы в -eотношении /, однако цитаты все еще необходимы, как я только что видел. >Интерпретируется непосредственно оболочки в качестве оператора перенаправления Я думаю , что , так как я получил эту ошибку:cannot create @2/d0: Directory nonexistent
seshoumara
Ах да, я не учел >. Вам нужны цитаты, в конце концов. Извинения за (попытку) ввести в заблуждение! И хотя добавление обратной косой черты выглядит как один символ, его необходимо удвоить в s///замене, так что никакой пользы нет ...
Тоби Спейт
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
Тит
@ Титус, я не понимаю. Можете ли вы уточнить немного?
Исмаэль Мигель
В PHP до 7-й версии был модификатор шаблонаe , который был заменен на preg_replace_callbackи мог быть использован для злоупотребления ... но это не совсем так.
Титус
@Titus Этот модификатор patern использовался, чтобы сказать, что вывод будет реальным кодом PHP, и попытаться сохранить правильный синтаксис. Здесь это не используется, но замените каждый отдельный символ частью кода для выполнения, независимо от его синтаксиса. Неверные данные приведут к серьезным проблемам безопасности.
Исмаэль Мигель
Я знаю. Но это похоже.
Тит
2

Пакет, 61 байт

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

Перевод @ xnor's xcellent Python ответа.

Нил
источник
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 возвращает число с плавающей запятой при использовании /и intdivслишком много байтов, поэтому мы делаем сдвиг вправо .

Обновления

  1. Сохранены 2 байта путем сокращения $i=$i>>1до $i>>=1целочисленного деления.
  2. Выкинул eval в пользу троичных операторов.
YetiCGN
источник
2

Python 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 байт

Golfed

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<-к работе, можно сэкономить несколько байтов (уточните каждую функцию с помощью bafter "-"="+"="/"="*"). Первоначально пытался заменить и разобрать eval, но порядок операций и скобки были ужасающими.

Vlo
источник
Это год спустя, но мне удалось получить его 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}

Ungolfed:

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

Полная программа, которая принимает входные данные в виде строки и печатает результат.

Это порт ответа @ xnor на Python .

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

Как это работает

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 
TheBikingViking
источник
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
Включите bytecount в свой заголовок, удалите ненужные пробелы и используйте 1-буквенные имена переменных.
TuxCrafting
Это вообще игра в гольф ?! :-D
YetiCGN
@ TùxCräftîñg Я сделал это.
Винни-Пух
Вы делите и умножаете на 1; вам нужно разделить и умножить на2
TuxCrafting
@ TùxCräftîñg Я сделал это.
Винни-Пух