Menos, Mais, Tempos, Exponenciação?


26

Este é um CMC (mini desafio de bate-papo) que eu publiquei em nossa sala de chat, The Ninteenth Byte , um pouco atrás.

O desafio

Dado um número inteiro positivo x, dependendo dos últimos 2 bits de x, faça o seguinte:

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

Entrada / Saída

Single Integer -> Single Integer  

Uma nova linha à direita é permitida na saída. Nenhum outro espaço em branco é permitido.

Casos de teste

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

Este é um desafio do , portanto o código mais curto vence!


8
O não deve 0caso seja x + 2, vendo como os outros são x * 2, x ^ 2e x ^^ 2(tetração)? : P
ETHproductions

Qual é o maior resultado que devemos apoiar (em relação a x ^ x)? 32 bits já não é suficiente para o caso de teste 11e 64 bits não é suficiente para o caso de teste 19.
Kevin Cruijssen

@KevinCruijssen Vou dizer que você só precisa lidar com casos em que a entrada e a saída estão no escopo do seu idioma, desde que o seu programa funcione teoricamente, considerando o tamanho infinito do número.
HyperNeutrino

@HyperNeutrino Ok, nesse caso eu fixo minha (7 Java) código (para +72 bytes .. xD)
Kevin Cruijssen

Respostas:


13

Geléia , 8 bytes

ị“+×*_”v

Experimente online!

Como funciona

Em primeiro lugar, observe que x&3é equivalente a x%4, onde %está o módulo. Então, como o Jelly usa indexação modular ( a[n] == a[n+len(a)]), não precisamos nem lidar com isso.

Então:

  • Se x%4==0, retornar x_x(subtração) (por consistência);
  • Se x%4==1retornar x+x;
  • Se x%4==2, retornar x×x(multiplicação);
  • Se x%4==3retornar x*x(exponenciação)

Observe que o Jelly usa a indexação 1, então a subtração "_"é movida para o final.

ị“+×*_”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 Jelly tem sua própria codificação - veja aqui , mas eu sei que todos os seus personagens têm 1 byte.
Stephen

"8 bytes". Como os bytes devem ser contados? Essa resposta consiste em oito caracteres, mas pelo menos na troca de pilha de codificação serve para esta página, ela ocupa 15 bytes (contados usando wc --bytes).
andrybak

Se os interpreta língua lo em uma codificação, não faz sentido usar outra codificação para a contagem de bytes (imo)
Mackenzie McClane

@andrybak O código codificado em uma codificação para que o navegador a mostre corretamente é de 15 bytes. O código em uma codificação que Jelly entende que é 8 bytes. Veja github.com/DennisMitchell/jelly/wiki/Code-page se você quiser saber como é codificado.
Etoplay


9

CJam , 12 bytes

ri__"-+*#"=~

Experimente online!

Explicação

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.

Executa uma das seguintes operações, dependendo xdo valor do mod 4 (o mod 4 é equivalente a AND 3).

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

6

Mathematica 25 Bytes

0[2#,#*#,#^#][[#~Mod~4]]&

Guardado 4 bytes graças a @MartinEnder


4

Pitão, 8 bytes

.v@"0y*^

Intérprete


Sim, eu testei isso e funciona. E não, não posso usar em vvez de .v.
Erik the Outgolfer

Eu pensei que o escopo era local ... Eu pensei .vque não podia acessar Q... Aparentemente, fui derrotado em Pyth. +1 para você.
Leaky Nun

@LeakyNun Não, é o vque tem escopo local, .vapenas avalia uma expressão.
Erik the Outgolfer

Eu tenho muito a aprender ...
Leaky Nun

3
Isso é bonito! Isso é absolutamente incrível! Eu não tinha ideia do que era possível. Para pontos de estilo, "0y*^poderia ser "-+*^.
Isaacg



3

Haskell, 28 27 bytes

f x=cycle[0,x+x,x*x,x^x]!!x

Experimente online!

Editar: Obrigado a Ørjan Johansen por 1 byte.


Hm, estou muito atrasado, mas você pode reduzir este byte com cycle.
Ørjan Johansen

@ ØrjanJohansen: antes tarde do que nunca. Obrigado!
N


2

Bytes C, 63 ou 62

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

-1 byte se macros são permitidas, assumindo que xnão seja uma expressão como 3+5(já que isso atrapalharia a precedência):

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

@ceilingcat Certo, esqueci disso.
Tim Čas

não compila no MSVS2015; O Intellisense disse que o cast to incomplete array type "int[]" is not allowedCompiler disse error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; ALÉM DISSO! onde está int f (int x)? o código é realmente pelo menos 8 bytes mais longo; Também é muito lento e ineficiente, como ele avalia everytning - não repita isso IRL)

@ xakepp35 O que? 1) ele precisa compilar em um compilador C. A maioria dos compiladores C (leia-se: praticamente todos, exceto o MSVC) suportam essa (int[])sintaxe para esta situação. 2) f(x)é perfeitamente legal C89. Eu não especifiquei o padrão. 3) Trata-se do tamanho do código, não da eficiência. E 4) Se você vai ser condescendente, pelo menos use um compilador real e / ou verifique seus fatos.
Tim Čas

@ Tim Čas Ah sim, desculpe-me! Eu estava tentando compilá-lo como código C ++. A culpa é minha) Compila e funciona muito bem!

2

Java 7, 75 bytes

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);}

Embora seja válido de acordo com as regras, longtenha 64 bits, falha nos casos de teste de exponenciação 19^19acima e acima. Para corrigir isso, podemos usar uma BigDecimalabordagem:

148 146 bytes

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);}

Explicação (da abordagem 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

Código do teste:

Experimente aqui.

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) + "; ");
    }
  }
}

Saída:

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; 

Você não precisa consertar o programa desta maneira: P A resposta antiga funcionaria se os números tivessem tamanho infinito; o primeiro programa teria sido válido sob minhas especificações. : P
HyperNeutrino

@HyperNeutrino Então eu especifico isso na resposta .. Ah, bem, Java não vencerá nenhum desafio de código-golfe de qualquer maneira. ;)
Kevin Cruijssen

1
Sim, eu especificaria. E sim, é Java, não vai ganhar. : D
HyperNeutrino

2
" E sim, é Java, não vai ganhar.: D " Estou acostumado a isso. : P Até a minha resposta Java mais curta de todos os 8 bytes é muito longa, em comparação com as respostas do golfe. xD Embora tenha sido a primeira vez que bati em uma resposta em Python com a minha resposta em Java, que deve contar com algo que eu acho. ;)
Kevin Cruijssen

2

Montador x86, sintaxe Intel, 192 bytes

.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

O exemplo pretende obter a velocidade de trabalho mais rápida. Is é um programa ou parte do programa que utiliza a convenção de chamada rápida. Ele assume a variável de entrada xno registro eaxe retorna o resultado também emeax . A idéia básica é evitar o uso de saltos condicionais, como em alguns exemplos aqui. Além disso, não é para avaliar tudo (como no exemplo C com matrizes), mas para usar matriz de ponteiros para funções e fazer saltos incondicionais mais rápidos (jmp / call) como um analógico otimizado "Alternar linguagem C () - caso ..". Essa técnica também pode ser útil em tipos de autômatos finita - como emuladores de processadores, executores e assim por diante.

Upd: para x64, use "r" nos nomes dos registradores, em vez de "e" (por exemplo, em raxvez de eax, em rcxvez de ecx). O tamanho não será alterado e usará palavras não assinadas de 64 bits.


Bem-vindo ao PPCG! O objetivo desse desafio é tornar seu código o mais curto possível. Nesse caso, seu código pode ser facilmente reduzido, combinando todas essas declarações de função. Você também pode remover alguns espaços em branco.
HyperNeutrino

@HyperNeutrino asm em si é meio "longo" idioma :), então eu não tenho uma idéia de como tornar isso mais curto. algum exemplo de conselhos?

Desculpe, devo ter copiado meu comentário na sua resposta C para este post. Não sei como programar no ASM, mas você poderia remover algum espaço em branco?
HyperNeutrino

@HyperNeutrino, desculpe .. mas não parece) que tem de ser um código mais longo entre outros, i pode janelas apenas TRUNC CrLf para o formato linux tão 209-> 192 bytes, as alterações não são visíveis)

Aw. Isso é ruim. Mas boa apresentação, independentemente! :)
HyperNeutrino

2

C #, 39 bytes

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

Explicação

Observe aquilo:

(xx, x + x, x * x, x ^ x) == (0, 2, x, x ^ (x-1)) * x

A solução cria uma matriz, indexa-a e multiplica o resultado por x:

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

Versões alternativas:

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

(39B, toda multiplicação feita na matriz, x%4substitui x&3)

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

(39B, o mesmo que a resposta da @ MetaColon, mas x%2*2*xsubstituindo x*x%4<1?0:2)


1

Na verdade , 12 bytes

;;3&"-+*ⁿ"Eƒ

Experimente online!

Explicação:

;;3&"-+*ⁿ"Eƒ
;;            two copies of input (so 3 total)
  3&          bitwise AND with 3
    "-+*ⁿ"E   index into this string
           ƒ  call the respective function



1

Oásis , 25 bytes

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

Experimente online!

Como funciona

Observe que x&3é equivalente a x%4, onde %está o módulo.

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 é uma linguagem baseada em pilha em que cada caractere é um comando.



1

C #, 42 bytes

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

Na verdade, é C # normal, mas como você não pode executá-lo como um programa inteiro e precisa digitá-lo no interativo, acho que você pode chamá-lo de C # interativo .

Explicação :

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)

Não sei dizer se é a variante mais curta, todas as sugestões são bem-vindas.


Eu não acho que isso seja válido. Você geralmente deve enviar um programa ou função . Snippets não são permitidos por padrão.
Cyoce

@Cyoce É um programa. Você só precisa executá-lo através do interativo, que interpretará o programa.
MetaColon

Quando executo isso de forma interativa, recebo um erro porque xnão está definido. Isso faz dele um trecho, não um programa completo.
Cyoce

@Cyoce No desafio dito, haveria uma variável x definida.
MetaColon 01/05/19

Não é isso que isso significa. "Dado um número inteiro positivo x" significa que você está recebendo x um método de entrada padrão (ou seja, função ou programa).
Cyoce




1

C, 115 bytes

#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))

Exemplo é uma função int f(int x)

Pretende obter a velocidade de trabalho mais rápida, pois mantém a CPU longe de saltos condicionais. E esta é apenas a maneira correta de otimização de velocidade para esta tarefa. Além disso, ele tenta não avaliar tudo, como no exemplo da matriz C, return(int[]){0,x+x,x*x,pow(x,x)}[x%4];mas usar sabiamente a matriz de ponteiros para funções, a fim de fazer saltos incondicionais muito mais rápidos (jmp / call) com aritmética de endereços muito mais rápida, como uma versão otimizada de " switch () - caso .. ". Essa técnica também pode ser útil em vários tipos de autômatos finita - como emuladores de processadores, executores, analisadores de fluxo de comando e assim por diante - onde a velocidade importa e o código como switch(x%4) case(0):... case(1):... é inadequado porque produz várias instruções cmp / jnz; e essas são operações caras para a CPU

O programa de teste mais simples e mais curto (em condições padrão) para o caso será o seguinte:

D(main,f(x))

Ele adicionará apenas 12 bytes de carga útil e totalizará nosso tamanho para 127 bytes;

Mas é melhor dizer ao vinculador para usar a ffunção como um ponto de entrada, em vez de main. É assim que, se pretendermos obter o binário de trabalho mais rápido possível para esta tarefa a partir do código mais curto ;-) Isso acontece porque a biblioteca C adiciona código extra de inicialização / desligamento antes de chamar sua função main ().

O código é compilado no MSVS Community 2015 sem truques e problemas e produz resultados corretos. Não testei com o gcc, mas tenho certeza de que também funcionará bem.


1
Bem-vindo ao PPCG! O objetivo desse desafio é tornar seu código o mais curto possível. Nesse caso, seu código pode ser facilmente reduzido, combinando todas essas declarações de função. Você também pode remover alguns espaços em branco.
HyperNeutrino

Eu gosto da idéia de usar ponteiros para funções
RosLuP

@RosLuP ye, mas é quase duas vezes maior que a sua versão de 60 bytes. mas funciona muito mais rápido, vale o seu tamanho.

@Hyper Neutrino Okay. Eu o comprimi mais. Parece, esta é a versão final! Não há bugs, todos os testes foram aprovados 8-)

@ xakepp35 você mediu o seu é mais rápido que o meu?
RosLuP

1

R, 47 42 bytes

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

Aplica-se a função de -, +, *, ou ^com base no módulo de xa xe x.

-é a única coisa (um pouco) inteligente, pois x-xsempre é 0.

R, 33 bytes

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

O mesmo método que outras pessoas usam. Embora seja mais curto, não gosto tanto.


0

Pyth , 12 bytes

.vjd,+@"-+*^

Experimente online!

Como funciona

Em primeiro lugar, observe que x&3é equivalente a x%4, onde% está o módulo. Então, como Pyth usa indexação modular (a[n] == a[n+len(a)] ), não precisamos nem lidar com isso.

Então:

  • E se x%4==0 retornarx-x (por consistência);
  • E se x%4==1 retornarx+x;
  • E se x%4==2 retornarx*x;
  • Se x%4==3retornar x^x.

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

Mais sobre notação polonesa: Wikipedia (muito ruim se você estiver na Turquia).


Hã? Isso me parece demais. Veja minha resposta para detalhes.
Erik the Outgolfer


0

Vim, 50 bytes

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

Aqui, ^Vrepresenta a Ctrl+V, ^Rrepresenta Ctrl-Re^[ representa oesc chave

Funciona construindo primeiro a expressão e depois deixando bc avaliá-la. Espera a entrada na primeira linha em um buffer vazio.

Explicação:

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.

Quando eu digito ^Vapenas cola o que eu tenho na minha área de transferência, em vez do número ...
Leaky Nun

1
Experimente online! Além disso, você pode fazer em Dvez ded$
DJMcMayhem

0

Pitão, 9 bytes

@[0yQ*QQ^

Suíte de teste

Nada de especial está acontecendo aqui, apenas calcule os quatro valores e selecione um com indexação modular.

@[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

Lote, 135 bytes

@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%

Eu esperava criar a exponenciação construindo e avaliando uma cadeia de caracteres do formulário, [0+...+0, 2+...+2, x+...+x, x*...*x]dependendo dos dois últimos bits, xmas infelizmente o código para selecionar a operação demorou muito para ser expresso, porque eu não poderia usar *como forparâmetro, mas estava pelo menos, capaz de usar alguns truques de queda para jogar fora alguns bytes.


0

Retina , 87 bytes

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

Experimente online! (O link inclui o conjunto de testes.)

Explicação: As duas primeiras linhas convertem a entrada em unária e a duplicam (então agora temos x;x). As próximas duas linhas procuram um x&3de um 0ou 1e mudam x;xpara x;0ou x;2apropriadamente. As próximas duas linhas procuram x&3==3e mudam x;xpara o x;x;x;...;x;1;x( x xs). Isto significa que temos ou x;0, x;2, x;xou x;...;xe permanece a tudo multiplicar juntos e converter de volta para decimal. (O código de multiplicação é baseado no wiki da Retina, mas foi alterado para lidar com a multiplicação por zero.)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.