Минус, Плюс, Таймс, Экспонентация?


26

Это CMC (чат-мини-вызов), который я опубликовал в нашем чате, Ninteenth Byte , немного назад.

Соревнование

Учитывая положительное целое число x, в зависимости от последних 2 битов x, сделайте следующее:

x & 3 == 0: 0
x & 3 == 1: x + x
x & 3 == 2: x * x
x & 3 == 3: x ^ x (exponentiation)

Ввод, вывод

Single Integer -> Single Integer  

Конечный перевод строки разрешен в выходных данных. Никакие другие пробелы не допускаются.

Testcases

input       output
    1            2
    2            4
    3           27
    4            0
    5           10
    6           36
    7       823543
    8            0
    9           18
   10          100
   11 285311670611
   12            0

Это испытание , поэтому выигрывает самый короткий код!


8
Если не 0случай быть x + 2, видя, как остальные x * 2, x ^ 2и x ^^ 2(тетрация)? : P
ETHпродукция

Какой самый большой результат мы должны поддержать (относительно x ^ x)? 32-разрядного уже недостаточно для тестового примера 11, а 64-разрядного недостаточно для тестового примера 19.
Кевин Круйссен

@KevinCruijssen Я скажу, что вам нужно обрабатывать только те случаи, когда ввод и вывод находятся в области действия вашего языка, если ваша программа теоретически будет работать при бесконечном размере числа.
HyperNeutrino

@HyperNeutrino Хорошо, в этом случае я исправил мой (Java 7) код (для +72 байт .. xD)
Кевин Круйссен

Ответы:


13

Желе , 8 байт

ị“+×*_”v

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

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

Во-первых, обратите внимание, что x&3эквивалентно x%4, где %по модулю. Затем, поскольку Jelly использует модульную индексацию ( a[n] == a[n+len(a)]), нам даже не нужно иметь с этим дело.

Затем:

  • Если x%4==0вернуть x_x(вычитание) (для согласованности);
  • Если x%4==1вернусь x+x;
  • Если x%4==2вернуть x×x(умножение);
  • Если x%4==3вернуть x*x(возведение в степень)

Обратите внимание, что Jelly использует 1-индексирование, поэтому вычитание "_"перемещается до конца.

ị“+×*_”v  example input: 10
ị“+×*_”   index 10 of the string “+×*_”, which gives "×"
       v  evaluate the above as a Jelly expression,
          with 10 as the argument, meaning "10×" is the
          expression evaluated. The dyad "×" takes the
          second argument from the only argument, effectively
          performing the function to itself.

2
@andrybak AFAIK Желе имеет свою собственную кодировку - смотрите здесь , но я знаю, что все ее символы - 1 байт.
Стивен

"8 байт". Как должны учитываться байты? Этот ответ состоит из восьми символов, но, по крайней мере, в кодировке stackexchange обслуживает эту страницу, он занимает 15 байт (считается с помощью wc --bytes).
andrybak

Если язык интерпретирует его в одной кодировке, нет смысла использовать другую кодировку для подсчета байтов (imo)
Маккензи Макклейн

@andrybak Код, закодированный в кодировке, чтобы браузер правильно его отображал, составляет 15 байт. Код в кодировке, понятной Джелли, составляет 8 байт. Посмотрите на github.com/DennisMitchell/jelly/wiki/Code-page, если хотите узнать, как он закодирован.
Etoplay


9

CJam , 12 байт

ri__"-+*#"=~

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

объяснение

ri            e# Read an int from input (call it x).
  __          e# Duplicate x twice.
    "-+*#"    e# Push this string.
          =   e# Get the character from the string at index x (mod 4).
           ~  e# Eval that char, using the two copies of x from before.

Запускает одну из следующих операций в зависимости от xзначения mod 4 (mod 4 эквивалентно AND 3).

0:  -  Subtraction
1:  +  Addition
2:  *  Multiplication
3:  #  Exponentiation


4

Pyth, 8 байт

.v@"0y*^

переводчик


Да, я проверил это, и это работает. И нет, я не могу использовать vвместо .v.
Эрик Outgolfer

Я думал, что область была локальной ... Я думал, что .vне может получить доступQ ... Видимо, меня обошли в Pyth. +1 для вас.
Утренняя монахиня

@LeakyNun Нет, это vимеет локальную область видимости, .vпросто выражает выражение.
Эрик Outgolfer

У меня есть чему поучиться ...
Leaky Nun

3
Это красиво! Это абсолютно потрясающе! Я понятия не имел, что это даже возможно. Для очков стиля,"0y*^ может быть "-+*^.
Исаак





2

C, 63 или 62 байта

#include<math.h>
f(x){return(int[]){0,x+x,x*x,pow(x,x)}[x&3];}

-1 байт, если допустимы макросы, если предположить, что xэто выражение не похоже на 3+5(поскольку это испортит приоритет):

#include<math.h>
#define f(x)(int[]){0,x+x,x*x,pow(x,x)}[x&3]

@ceilingcat Правильно, забыл об этом.
Тим

не компилируется на MSVS2015; Intellisense сказал cast to incomplete array type "int[]" is not allowedкомпилятор сказал error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; ТАКЖЕ! где int f (int x)? код на самом деле как минимум на 8 байт длиннее; также он очень медленный и неэффективный, так как он оценивает все - не повторяйте его в

@ xakepp35 Что? 1) он должен составить в виде C компилятор. Большинство (читай: почти все, кроме MSVC) компиляторов C поддерживают этот (int[])синтаксис для этой ситуации. 2) f(x)совершенно легально с89. Я не указал стандарт. 3) Речь идет о размере кода, а не эффективности. И 4) Если вы собираетесь покровительствовать, используйте хотя бы настоящий компилятор и / или проверьте свои факты.
Тим

@ Тим Час Да, прости! Я пытался скомпилировать его как код C ++. Это моя вина) Он компилируется и прекрасно работает!

2

Java 7, 75 байт

long c(int n){int x=n%4;return x<1?0:x<2?n+n:x<3?n*n:(long)Math.pow(n,n);}

Несмотря на то, что он действителен в соответствии с правилами, longявляется 64-битным, поэтому он не подходит для тестов на возведение в степень 19^19и выше. Чтобы исправить это, мы можем использовать BigDecimalподход:

148 146 байт

import java.math.*;BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

Пояснение (подхода BigDecimal):

import java.math.*;                // Import required for BigDecimal
BigDecimal c(int n){               // Method with integer parameter and BigDecimal return-type
  int x=n%4;                       //  Input modulo-4
  BigDecimal m=new BigDecimal(n);  //  Convert input integer to BigDecimal
  return x<1?                      //  If the input mod-4 is 0:
    m.subtract(m)                  //   Return input - input (shorter than BigDecimal.ZERO)
   :x<2?                           //  Else if the input mod-4 is 1:
    m.add(m)                       //   Return input + input
   :x<3?                           //  Else if the input mod-4 is 2:
    m.multiply(m)                  //   Return input * input
   :                               //  Else:
    m.pow(n);                      //   Return input ^ input
}                                  // End of method

Тестовый код:

Попробуй это здесь.

import java.math.*;
class M{
  static BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

  public static void main(String[] a){
    for (int i = 1; i <= 25; i++) {
      System.out.print(c(i) + "; ");
    }
  }
}

Выход:

2; 4; 27; 0; 10; 36; 823543; 0; 18; 100; 285311670611; 0; 26; 196; 437893890380859375; 0; 34; 324; 1978419655660313589123979; 0; 42; 484; 20880467999847912034355032910567; 0; 50; 

Вам не нужно исправлять программу таким образом: P Старый ответ будет работать, если числа будут иметь бесконечный размер; Первая программа была бы действительна в соответствии с моими спецификациями. :П
HyperNeutrino

@HyperNeutrino Тогда я укажу это в ответе. Ну, ладно, Java в любом случае не выиграет ни одной задачи по коду. ;)
Кевин Круйссен

1
Да я бы уточнил. И да, это Java, это не победит. : D
HyperNeutrino

2
« И да, это Java, она не победит.: D » Я к этому привык. : P Даже мой самый короткий ответ на Java из 8 байтов является длинным по сравнению с ответами на игру в гольф. xD Хотя это был первый раз, когда я обыграл Python-ответ своим Java-ответом, что должно что-то значить. ;)
Кевин Круйссен

2

x86 Assembler, синтаксис Intel, 192 байта

.data
f dw @q,@w,@e,@r
.code
mov ecx, eax
and ecx, 3
mov edx,dword ptr f[ecx*4]
call [edx]
ret
q:
xor eax,eax
ret
w:
add eax,eax
ret
e:
mul eax,eax
ret
r:
mov ecx,eax
t:
mul eax,eax
loop t
ret

Пример претендует на самую высокую скорость работы. Is - это программа или часть программы, которая использует соглашение fastcall. Он предполагает входную переменную xв регистре eaxи возвращает результат также в eax. Основная идея - избегать использования условных переходов, как в некоторых примерах здесь. Кроме того, это не для оценки всего (как в примере C с массивами), а для использования массива указателей на функции и более быстрых безусловных переходов (jmp / call) в качестве оптимизированного аналога "языка переключения C () - case ..". Эта техника может быть полезна и для конечных автоматов, таких как эмуляторы процессоров, исполнители и так далее.

Upd: для x64 используйте «r» в именах регистров вместо «e» (например, raxвместо eax, rcxвместо ecx). Размер не будет изменен, и он будет использовать 64-битные слова без знака.


Добро пожаловать в PPCG! Цель этой задачи - сделать ваш код максимально коротким. В этом случае ваш код может быть легко сокращен путем объединения всех этих объявлений функций. Вы также можете удалить некоторые пробелы.
HyperNeutrino

@HyperNeutrino asm сам по себе является "длинным" языком :), поэтому у меня нет идеи о том, как сделать это короче. какой-нибудь пример-советы?

Извините, я, должно быть, скопировал свой комментарий на ваш ответ C в это сообщение. Я не знаю, как программировать на ASM, но не могли бы вы удалить некоторые пробелы?
HyperNeutrino

@HyperNeutrino, извините .. но кажется нет) это должен быть самый длинный код среди других, я могу просто усечь windows crlf до формата linux, чтобы 209-> 192 байта, изменения не были видны)

Aw. Это очень плохо. Но приятная подача независимо! :)
HyperNeutrino

2

C #, 39 байт

x=>new[]{0,2,x,Math.Pow(x,x-1)}[x&3]*x;

объяснение

Обратите внимание, что:

(хх, х + х, х * х, х ^ х) == (0, 2, х, х ^ (х-1)) * х

Решение создает массив, индексирует его, а затем умножает результат на x:

x => new[] { 0, 2, x, Math.Pow(x,x-1) }[x&3] * x;

Альтернативные версии:

x=>new[]{0,x+x,x*x,Math.Pow(x,x)}[x%4];

(39B, все умножение сделано в массиве, x%4заменяет x&3)

x=>x%4<2?x%2*2*x:Math.Pow(x,x%4<3?2:x);

(39B, такой же, как ответ @ MetaColon, но x%2*2*xзаменяет x*x%4<1?0:2)





1

Оазис , 25 байт

mn4%3Q*nkn4%2Q*nxn4%1Q*++

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

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

Обратите внимание, что x&3эквивалентно x%4, где %по модулю.

mn4%3Q*nkn4%2Q*nxn4%1Q*++  input is n
mn4%3Q*                    (n**n)*((n%4)==3)
       nkn4%2Q*            (n**2)*((n%4)==2)
               nxn4%1Q*    (n*2)*((n%4)==1)
                       +   add the above two
                        +  add the above two

Oasis - это основанный на стеке язык, где каждый символ является командой.



1

C #, 42 байта

x=>x%4<2?x*x%4<1?0:2:Math.Pow(x,x%4<3?2:x)

На самом деле это обычный C #, но поскольку вы не можете запустить его как целую программу, и вам нужно ввести его в интерактивном режиме, я думаю, вы можете назвать его C # интерактивным .

объяснение :

x => (x % 4) < 2     //If the bits are smaller than 2 (1 or 0)
? x *           //multiply x with
    (x % 4) < 1 //if the bits are 0
    ? 0         //0 (results in 0)
    : 2         //or else with 2 (results in 2*x or x+x)
: Math.Pow(x,   //otherwise power x by
    (x % 4) < 3 //if the bits are 2
    ? 2         //2 (results in x^2 or x*x)
    : x);       //or else x (results in x^x)

Не могу сказать, что это самый короткий вариант, любые предложения приветствуются.


Я не думаю, что это действительно. Как правило, вы должны представить программу или функцию . Фрагменты по умолчанию не разрешены.
Cyoce

@Cyoce Это программа. Вам просто нужно запустить его через интерактив, который будет интерпретировать программу.
MetaColon

Когда я запускаю это в интерактивном режиме, я получаю сообщение об ошибке, потому что xоно не определено. Это делает этот фрагмент, а не полную программу.
Cyoce

@Cyoce В заявке говорится, что будет определена переменная x.
MetaColon

Это не то, что это значит. «Заданное положительное целое число x» означает, что вам дают x стандартный метод ввода (т. Е. Функцию или программу).
Cyoce




1

C, 115 байтов

#include<math.h>
#define D(K,L)K(x){return L;}
D(q,0)D(w,x+x)D(e,x*x)D(r,pow(x,x))(*g[])()={q,w,e,r};D(f,g[x%4](x))

Пример - это функция int f(int x)

Он претендует на самую быструю скорость работы, поскольку не позволяет ЦП использовать условные переходы. И это единственный верный способ оптимизации скорости для этой задачи. Кроме того, он пытается не оценивать все, как в примере с массивом C, return(int[]){0,x+x,x*x,pow(x,x)}[x%4];но разумно использовать массив указателей на функции, чтобы сделать намного более быстрые безусловные переходы (jmp / call) с гораздо более быстрой адресной арифметикой, как оптимизированную версию " переключатель () - случай .. ". Этот метод также может быть полезен в некоторых типах конечных автоматов, таких как эмуляторы процессора, исполнители, анализаторы потока команд и т. Д., Где скорость имеет значение, а подобный код switch(x%4) case(0):... case(1):... не подходит, поскольку он генерирует несколько команд cmp / jnz; и это дорогостоящие операции для процессора

Самая простая и самая короткая тестовая программа (в условиях по умолчанию) для случая будет выглядеть следующим образом:

D(main,f(x))

Это добавит всего 12 байтов полезной нагрузки и увеличит наш размер до 127 байтов;

Но вам лучше сказать компоновщику использовать fфункцию в качестве точки входа, а не main. Именно так, если мы стремимся получить максимально быстрый рабочий двоичный файл для этой задачи из кратчайшего кода ;-) Это происходит потому, что библиотека C добавляет дополнительный код init / shutdown перед вызовом функции main ().

Код компилируется в MSVS Community 2015 без каких-либо уловок и проблем и дает правильные результаты. Я не проверял это с gcc, но я уверен, что он также будет работать нормально.


1
Добро пожаловать в PPCG! Цель этой задачи - сделать ваш код максимально коротким. В этом случае ваш код может быть легко сокращен путем объединения всех этих объявлений функций. Вы также можете удалить некоторые пробелы.
HyperNeutrino

Мне нравится идея использования указателей на функции
RosLuP

@RosLuP, но это почти вдвое длиннее, чем ваша 60-байтовая версия. но работает намного быстрее, стоит своих размеров.

@ Hyper Neutrino Хорошо. Я сжал это больше. Кажется, это окончательная версия!

@ xakepp35 ты замерял быстрее чем у меня?
РосЛюП

1

R, 47 42 байта

x=scan();c(`-`,`+`,`*`,`^`)[[x%%4+1]](x,x)

Применяет функцию -, +, *или ^на основе модуля xк xи x.

- единственная (несколько) умная вещь, так как x-x как всегда 0.

R, 33 байта

pryr::f(c(0,2*x,x^2,x^x)[x%%4+1])

Тот же метод, что и другие люди. Хотя это короче, мне это не так нравится.


0

Pyth , 12 байт

.vjd,+@"-+*^

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

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

Во-первых, обратите внимание, что x&3эквивалентно x%4, где %по модулю. Тогда, так как Pyth использует модульную индексацию (a[n] == a[n+len(a)] ), поэтому нам даже не нужно иметь с этим дело.

Затем:

  • Если x%4==0вернусьx-x (для согласованности);
  • Если x%4==1вернусьx+x;
  • Если x%4==2вернусьx*x;
  • Если x%4==3, возврат x^x.

.vjd,+@"-+*^  example input: 10
      @"-+*^  "-+*^"[10], which is "*"
     +        "*10"
    ,         ["*10","10"]
  jd          "*10 10"
.v            evaluate as Pyth expression
              (Pyth uses Polish notation)

Подробнее о польской нотации: Википедия (очень плохо, если вы в Турции).


А? Это просто кажется мне слишком много. Смотрите мой ответ для деталей.
Эрик Outgolfer

0

Japt , 13 байт

Ov"^+*p"gU +U

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

При этом используется тот же метод, что и в других ответах eval, за исключением того, что программа -Uпросто отрицает U, поэтому ^вместо него мы используем (побитовый XOR)


0

Vim, 50 байтов

y$o^R"A-+*^^V^[0^R"lx0"_Dp^[0D@"kJ0"ad$:r!echo ^R"^R0|bc^<Enter>

Здесь ^Vпредставляет собой Ctrl+V, ^Rпредставляет Ctrl-Rи ^[представляет escключ

Работает, сначала создав выражение, а затем позволяя bc оценить его. Ожидается ввод в первой строке в противном случае пустой буфер.

Объяснение:

y$o^R"                                                          Copies the input into register " and pastes it on the second line
      A-+*^^V^[0^R"lx0"_Dp                                      Enters that text after the input on the second line
                          ^[0D@"                                Executes the second line as a Vim command.
                                                                For example, if the input is 12, the second line would be 12A-+*^^[012lx0"_Dp, which means:
                                                                  12A-+*^^[           Insert the text -+*^ 12 times
                                                                           012lx0"_Dp Go 12 chars to the right and remove everything except for that.
                                                                If effect, this basically just selects the appropriate operation.
                                kJ0"ad$                         Put the operator after the number, cut it into register a
                                       :r!                      Execute the following shell command and put the result into the buffer:
                                          echo ^R"^R0|bc<Enter> The shell command "echo [contents of register a][contents of registers 0]|bc. As said above, register a contains the input and the operator, and register 0 contains the input. The <enter> then executes this command.

Когда я ^V
Leaky Nun

1
Попробуйте онлайн! Также Вы можете сделать Dвместоd$
DJMcMayhem

0

Pyth, 9 байт

@[0yQ*QQ^

Тестирование

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

@[0yQ*QQ^
@[0yQ*QQ^QQ)Q    Implicit variable introduction
@           Q    Modularly index into the following list
 [0        )     0
   yQ            Q*2
     *QQ         Q*Q
        ^QQ      Q^Q

0

Пакет, 135 байт

@set/an=%1*2^&6
@goto %n%
:6
@set n=1
@for /l %%i in (1,1,%1)do @set/an*=%1
@goto 0
:4
@set n=%1
:2
@set/an*=%1
:0
@echo %n%

Я надеялся создать возведение в степень, создавая и оценивая строку формы в [0+...+0, 2+...+2, x+...+x, x*...*x]зависимости от последних двух битов, xно, к сожалению, код для выбора операции занял слишком много времени, чтобы выразить, потому что я не мог использовать *в качестве forпараметра, но я был по крайней мере, в состоянии использовать некоторую хитрость падения, чтобы убрать несколько байтов.


0

Сетчатка , 87 байт

.+
$*1;$&$*
;((1111)*)(1?)$
;$3$3
1(?=1.*;((1111)*111)$)
$1;
+`\G1(?=.*;(1*))|;1*$
$1
1

Попробуйте онлайн!(Ссылка включает тестовый набор.)

Объяснение: первые две строки преобразуют ввод в унарный код и дублируют его (теперь мы имеем x;x). Следующие две строки искать x&3либо 0или 1и изменения x;xв x;0или x;2надлежащим образом . Следующие две строки ищут x&3==3и заменяют x;xна x;x;x;...;x;1;x( x xs). Это означает , что мы имеем либо x;0, x;2, x;x, или x;...;xи остается умножить все вместе и преобразовать обратно в десятичной системе . (Код умножения основан на коде в вики Retina, но изменен для обработки умножения на ноль.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.