Ajude-me a procrastinar nos reparos do meu computador!

23

Esse desafio é trazido a você por inspiração real (e trágica). Recentemente, a linha numérica no meu teclado tem sido um pouco esporádica. As teclas 1-9funcionam algumas vezes - mas outras vezes não têm resultado. Como um programador ávido, isso é horrível! (Veja esse ponto de exclamação? É assim que você sabe que eles estão trabalhando no momento.) Não só preciso dos números, mas também dos símbolos!@#$%^&*(são completamente ineficazes metade do tempo também! Como programador em C, em vez de tirar um tempo da minha agenda ocupada de rabiscar o código para consertar meu laptop, fiquei mais interessado em solucionar o problema. Ao longo das últimas semanas, lentamente, todos os literais numéricos no meu código foram substituídos por hexadecimal, para que eu não precise procurar por números para copiar e colar. No entanto, alguns números não são fáceis de digitar sem as teclas 1-9. Por exemplo, o número 1não pode ser escrito de maneira tão simples em hexadecimal, e eu tentei substituir 1s no meu código por 0xF - 0xE. As únicas chaves que são afetadas são 1-9, por isso, manter o pleno uso de símbolos como +, -, e /. No entanto, não posso usar multiplicação ou parênteses, pois*e (são frequentemente quebrados. Isso leva ao seu desafio.

Entrada

Um número inteiro, npara stdin ou equivalente do seu idioma. Se desejar, o número inteiro pode ser precedido ou seguido por uma nova linha ou outro caractere de espaço em branco. Como alternativa, você pode receber entrada por meio de um argumento de linha de comando.

Seu programa deve responder à entrada negativa corretamente e ser capaz de manipular pelo menos números inteiros assinados de 32 bits.

Saída

Seu programa deve gerar, de alguma forma observável, a maneira mais curta (em caracteres que não sejam espaços em branco) possível de escrever o número ncomo uma soma, diferença ou divisão de um ou mais valores hexadecimais. Há mais de uma maneira de resolver esse problema e não há requisitos para que você defina qualquer saída de tamanho igual a qualquer outra.

A saída deve estar no formato em A % A % A...que Aé um valor hexadecimal a seguir 0xcontendo apenas dígitos A-F a-fe %é um dos símbolos -+/. Vamos /descrever a divisão inteira, não o ponto flutuante.

(Observe que sua saída deve resultar na navaliação de divisões primeiro, da esquerda para a direita e, em seguida, em adições e subtrações, da esquerda para a direita, conforme convenção).

Casos de teste

Saída de entrada

  1. 1

    0xF - 0xE(ou 0xF-0xEou 0xB-0xAou 0xd - 0xcou 0xF/0xF)

  2. 15

    0xF

  3. 255

    0xFF

  4. 30

    0xF + 0xF

Pontuação e Regras

Isso é código-golfe. Sua pontuação preliminar é o número de bytes no seu arquivo de origem.

Você NÃO pode usar nenhum dos dígitos 1-9da sua fonte.

Você PODE usar símbolos !@#$%^&*(na sua fonte, mas cada um tem uma penalidade de +20 na sua pontuação.

Seu programa pode ser substituído por uma função que aceita ncomo argumento, desde que essa função produz alguma forma de saída legível por humanos. O valor de retorno da sua função NÃO conta como saída.

As brechas padrão não são permitidas.

Menor pontuação ganha! Boa sorte!

Eu criei alguma formatação / questionamento / clareza? Avise-se me! Esta é a minha primeira submissão a este site!

BrainSteel
fonte
Existe um limite superior para o tamanho do número inteiro? Além disso, os números negativos serão representados com alguma precisão arbitrária (ou seja, 32 bits)?
FryAmTheEggman
@FryAmTheEggman Editou a postagem original para esclarecer. A entrada pode ser negativa e seu programa deve responder corretamente a pelo menos 32 bits de entrada. Obrigado!
BrainSteel
Isso me parece uma especificação bastante sólida, mas se você quiser algum feedback, recomendo publicá-lo na sandbox (para futuros desafios) para que você possa obter feedback antes de publicá-lo no main e as pessoas começarem a trabalhar nele .
Martin Ender
1
Divisão de número inteiro ou ponto flutuante?
edc65 21/02

Respostas:

5

JavaScript 287 (187 + 20 * 5) 295 (195 + 20 * 5) 338 (198 + 20 * 7)

Uma função que verifica todas as combinações possíveis dos 6 dígitos hexadecimais permitidos (0xA a 0xF) e dos 3 operadores permitidos. Saída via pop-up e não retornando um valor, conforme solicitado.

Eu usei [] para grupo separados por vírgulas expressão, mas não podia evitar 5 7 suportes abertos para loops e função de chamada.
Para evitar dígitos, existem variáveis ​​A, B, C para 1,2,3 (isso torna o código ainda mais obscuro)

Editar código revisado com o objetivo de evitar '('. Removido ife criação explícita de RegExp

Cuidado: essa função é incrivelmente lenta, excederá o limite de tempo para um script no FireFox, mesmo para pequenas entradas como 90.

Para enumerar toda a expressão possível, uso o número começando em 3 e subindo para sempre. Codificação de dígitos:
0,1,2 são os operadores +, -, /
4 a 9 são os dígitos hexadecimais A..F
3 não é permitido
Cada número é verificado com uma regexp /3|[0-2]{2}/para evitar o dígito 3 e ter 2 operadores consecutivos (o verifique também evitar traling e operadores líderes - ver código)

A string resultante é algo como 0xA + 0xA - 0xDjavascript válido, então eu uso o eval para avaliá-lo. Infelizmente, o operador '/' é ponto flutuante e não é inteiro no JavaScript, portanto, não tenho 100% de certeza de que o resultado seja a conversão correta de eventos para o resultado final inteiro (mas estou bastante confiante, pois um pequeno erro de arredondamento não pode amplificado por um '*')

F=x=>{
  for(A=-~0,B=A+A,i=C=A+B,j=0;j?x-~~eval(L):A;)
  {
    j=++i+'0',k=0+j;
    for(c of~k.search(C+'|[0-'+B+']{'+B+'}',L='',w='0x')?j='':j)
      c>C?w+=' ABCDEF'[c-C]:[L+=w,w=' '+'+-/'[c]+' 0x']
  }
  alert(L)
}

Algo mais

Agora, algo mais engraçado. Usei um analisador de expressão simplificado demais para evitar a chamada de avaliação e, divertidamente, isso acabou sendo muito mais rápido.

O analisador é realmente simplificado, em um analisador real V e O devem ser matrizes contendo a pilha de valores pendentes e a pilha de operadores pendentes. Aqui V é o único valor pendente (e também o valor de retorno) e O é uma sequência com no máximo 2 caracteres. P contém a tabela de precedência de operadores, para '- + /' => '112'

Isso marca 275 + 4 * 20 => 355

F=x=>{
  for(A=-~0,B=A+A,i=C=A+B,D=A+C,j=0,P=''+A+A+B;j?x-V:A;)
  {
    j=++i+'0',k=0+j;
    for(c of~k.search(C+'|[0-'+B+']{'+B+'}',v=V=O=L='',w='0x')?j='':j)
      c>C?
        w+='ABCDEF'[v<<=D,v+=D+A-~c,c-D]
      :[
          P[O[0]]>=P[c]?[v=O>A?V/v|0:O>0?V+v:V-v,O=c]:O=c+O,
          L+=w,w=' '+'-+/'[c]+' 0x',V=v,v=0
      ]
  }
  alert(L)
}

Teste No console Firefox / FireBug, altere o alerta com retorno (muito mais utilizável)

;[0, 1, 15, 255, 30].forEach(x=>console.log(x,F(x)))

0 0xA - 0xA
1 0xA / 0xA
15 0xF
255 0xFF
30 0xF + ​​0xF

Apenas um pouco menos óbvio (mas seja paciente)

;[16,40, 51, 62, 73, 84, 95].forEach(x=>console.log(x,F(x)))

16 0xBA / 0xB
40 0xA + 0xF + ​​0xF
51 0xDD - 0xAA
62 0xEA - 0xAC
73 0xA + 0xEA - 0xAB
84 0xFE - 0xAA
95 0xA + 0xFF - 0xAA

edc65
fonte
3

Python 2: 185 bytes + 2 * 20 = 225

Tempo demais para uma resposta séria. Mas como ainda não há respostas, postarei de qualquer maneira.

from itertools import product as p
n=input()
l=t=0
while~l:
 l=-~l
 for i in p("0xABCDEF+-/",repeat=l):
  j=""
  for k in i:j+=k
  try:exec"t="+j
  except:0
  if t==n:print j;l=~0;break

productcria todos os diferentes arranjos dos caracteres permitidos. exectenta decodificá-lo. Infelizmente, isso retorna uma exceção, daí o longo try - catchbloco. O resultado é bom, imprime e existe.

Penalidade de 2 vezes, por causa desses aparelhos durante as chamadas de função.

Jakube
fonte
2
Essa resposta pode ter alguns problemas: (1) 0não é um literal hexadecimal; (2) A divisão que envolve um número negativo em Python dá um resultado diferente do que em C.
feersum