Aidez-moi à remettre à plus tard les réparations de mon ordinateur!

23

Ce défi vous est apporté par une inspiration réelle (et tragique). Récemment, la rangée de chiffres sur mon clavier a été un peu sporadique. Les touches 1-9fonctionnent parfois - mais parfois elles n'ont aucun résultat. En tant que programmeur passionné, c'est horrible! (Voir ce point d'exclamation? C'est ainsi que vous savez qu'ils fonctionnent en ce moment.) Non seulement j'ai souvent besoin des chiffres eux-mêmes, mais des symboles!@#$%^&*(sont également totalement inefficaces la moitié du temps! En tant que programmeur C, plutôt que de prendre du temps sur mon emploi du temps chargé de griffonner du code pour réparer mon ordinateur portable, je suis plus intéressé à contourner le problème. Au cours des dernières semaines, lentement, tous les littéraux numériques de mon code ont été remplacés par des hexadécimaux afin que je n'aie pas à chercher des nombres à copier et coller. Cependant, certains chiffres ne sont pas faciles à taper sans les clés 1-9. Par exemple, le nombre 1ne peut pas être écrit si simplement en hexadécimal, et j'ai eu recours à remplacer 1s dans mon code par 0xF - 0xE. Les seules touches qui sont touchées sont 1-9, donc je maintiens la pleine utilisation de symboles tels que +, -et /. Cependant, je ne peux pas utiliser de multiplication ou de parenthèses, car* et( sont souvent cassés. Cela mène à votre défi.

Contribution

Un nombre entier, n à stdin ou l'équivalent de votre langue. Si vous le souhaitez, l'entier peut être précédé ou suivi d'une nouvelle ligne ou d'un autre caractère d'espacement. Vous pouvez également recevoir une entrée via un argument de ligne de commande.

Votre programme doit répondre correctement aux entrées négatives et être capable de gérer au moins des entiers signés 32 bits.

Sortie

Votre programme doit générer, sous une forme observable, la manière la plus courte (en caractères non blancs) d'écrire le nombre nsous la forme d'une somme, d'une différence ou d'une division d'une ou plusieurs valeurs hexadécimales. Il existe plusieurs façons de résoudre ce problème, et il n'est pas nécessaire de privilégier une sortie de longueur égale par rapport à une autre.

La sortie doit être sous la forme A % A % A...Aest une valeur hexadécimale après 0xne contenant que des chiffres A-F a-f, et %est l'un des symboles-+/ . Laissez /décrire la division entière, sans virgule flottante.

(Notez que votre sortie devrait entraîner n lors de l'évaluation des divisions en premier, de gauche à droite, puis des ajouts et soustractions, de gauche à droite, comme c'est la convention.)

Cas de test

Entrée sortie

  1. 1

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

  2. 15

    0xF

  3. 255

    0xFF

  4. 30

    0xF + 0xF

Scoring et règles

C'est du code-golf. Votre score préliminaire est le nombre d'octets dans votre fichier source.

Vous ne pouvez utiliser aucun des chiffres 1-9 de votre source.

Vous pouvez utiliser des symboles !@#$%^&*( dans votre source, mais chacun vient à une pénalité de +20 à votre score.

Votre programme peut être remplacé par une fonction qui prend n comme argument tant que cette fonction produit une forme de sortie lisible par l'homme. La valeur de retour de votre fonction ne compte PAS comme sortie.

Les échappatoires standard ne sont pas autorisées.

Le score le plus bas gagne! Bonne chance!

Ai-je fait quelque chose de formatage / questionnement / clarté? Faites le moi savoir! Ceci est ma première soumission sur ce site!

BrainSteel
la source
Y a-t-il une limite supérieure à la taille de l'entier? De même, les nombres négatifs seront-ils représentés avec une précision arbitraire (c'est-à-dire 32 bits)?
FryAmTheEggman
@FryAmTheEggman Modifié le message d'origine pour clarifier. L'entrée peut être négative et votre programme doit répondre correctement à une entrée d'au moins 32 bits. Merci!
BrainSteel
Cela ressemble à une spécification assez solide pour moi, mais si vous souhaitez des commentaires, je vous recommande de les publier dans le bac à sable (pour les défis futurs) afin que vous puissiez obtenir des commentaires avant de les publier sur Main et que les gens commencent à y travailler. .
Martin Ender
1
Division entière ou virgule flottante?
edc65

Réponses:

5

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

Une fonction qui vérifie toutes les combinaisons possibles des 6 chiffres hexadécimaux autorisés (0xA à 0xF) et des 3 opérateurs autorisés. Sortie via popup et ne retournant pas de valeur, comme demandé.

J'ai utilisé [] pour regrouper l'expression séparée par des virgules, mais je n'ai pas pu éviter 5 7 crochets ouverts pour les boucles et les appels de fonction.
Pour éviter les chiffres, il existe des variables A, B, C pour 1,2,3 (cela rend le code encore plus obscur)

Modifier le code révisé en se concentrant sur l'évitement de '('. Suppression de ifs et création explicite de RegExp

Attention: cette fonction est incroyablement lente, elle dépassera la limite de temps pour un script dans FireFox, même pour une petite entrée comme 90.

Pour énumérer toutes les expressions possibles, j'utilise un nombre commençant à 3 et remontant pour toujours. Codage des chiffres:
0,1,2 sont les opérateurs +, -, /
4 à 9 sont les chiffres hexadécimaux A..F
3 n'est pas autorisé
Chaque nombre est vérifié avec une expression rationnelle/3|[0-2]{2}/ pour éviter le chiffre 3 et avoir 2 opérateurs consécutifs (le vérifier également éviter les essais et les opérateurs principaux - voir code)

La chaîne résultante est quelque chose comme 0xA + 0xA - 0xDça est du javascript valide, donc j'utilise eval pour l'évaluer. Malheureusement, l'opérateur '/' est en virgule flottante et non entier en JavaScript, donc je ne suis pas sûr à 100% que le résultat soit une conversion correcte des événements pour entier le résultat final (mais je suis assez confiant, étant donné qu'une petite erreur d'arrondi ne peut pas être amplifié par un '*')

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

Autre chose

Maintenant, quelque chose de plus drôle. J'ai utilisé un analyseur d'expression simplifié pour éviter l'appel eval et, de manière amusante, cela s'est avéré beaucoup plus rapide.

L'analyseur est vraiment simplifié, dans un véritable analyseur, V et O devraient être des tableaux contenant la pile de valeurs en attente et la pile d'opérateurs en attente. Ici, V est la seule valeur en attente (et également la valeur de retour) et O est une chaîne avec au plus 2 caractères. P contient la table de priorité des opérateurs, pour '- + /' => '112'

Cela donne 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)
}

Testez dans la console Firefox / FireBug, changez d'alerte avec retour (beaucoup plus utilisable)

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

Un peu moins évident (mais soyez patient)

;[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
la source
3

Python 2: 185 octets + 2 * 20 = 225

Trop long pour une réponse sérieuse. Mais comme il n'y a pas encore de réponse, je le posterai quand même.

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

productcrée tous les différents arrangements des caractères autorisés. execessaie de le décoder. Cela renvoie malheureusement une exception, de là la longuetry - catch bloc. Si le résultat est bon, il imprime et existe.

2 fois la pénalité, à cause de ces accolades lors des appels de fonction.

Jakube
la source
2
Cette réponse pourrait avoir quelques problèmes: (1) 0n'est pas un littéral hexadécimal; (2) Une division impliquant un nombre négatif en Python donne un résultat différent de celui en C.
feersum