Écrivez un programme d'assemblage GOLF qui, étant donné un entier non signé 64 bits dans le registre, n
place une valeur non nulle dans le registre s
si n
est un carré, sinon 0
dans s
.
Votre binaire GOLF (après assemblage) doit tenir dans 4096 octets.
Votre programme sera noté à l'aide du programme Python3 suivant (qui doit être placé dans le répertoire GOLF ):
import random, sys, assemble, golf, decimal
def is_square(n):
nd = decimal.Decimal(n)
with decimal.localcontext() as ctx:
ctx.prec = n.bit_length() + 1
i = int(nd.sqrt())
return i*i == n
with open(sys.argv[1]) as in_file:
binary, debug = assemble.assemble(in_file)
score = 0
random.seed(0)
for i in range(1000):
cpu = golf.GolfCPU(binary)
if random.randrange(16) == 0: n = random.randrange(2**32)**2
else: n = random.randrange(2**64)
cpu.regs["n"] = n
cpu.run()
if bool(cpu.regs["s"]) != is_square(n):
raise RuntimeError("Incorrect result for: {}".format(n))
score += cpu.cycle_count
print("Score so far ({}/1000): {}".format(i+1, score))
print("Score: ", score)
Assurez-vous de mettre à jour GOLF vers la dernière version avec git pull
. Exécutez le programme de score à l'aide de python3 score.py your_source.golf
.
Il utilise une graine statique pour générer un ensemble de nombres dont environ 1/16 est carré. L'optimisation vers cet ensemble de chiffres est contraire à l'esprit de la question, je peux changer la graine à tout moment. Votre programme doit fonctionner pour tout numéro d'entrée 64 bits non négatif, pas seulement ceux-ci.
Le score le plus bas l'emporte.
Parce que GOLF est très nouveau, je vais inclure quelques pointeurs ici. Vous devriez lire la spécification GOLF avec toutes les instructions et les coûts de cycle . Dans le référentiel Github, des exemples de programmes peuvent être trouvés.
Pour les tests manuels, compilez votre programme en binaire en exécutant python3 assemble.py your_source.golf
. Ensuite, exécutez votre programme en utilisant python3 golf.py -p s your_source.bin n=42
, cela devrait démarrer le programme avec n
la valeur 42 et imprimer le registre s
et le nombre de cycles après la sortie. Voir toutes les valeurs du contenu du registre à la sortie du programme avec le -d
drapeau - utilisez --help
pour voir tous les drapeaux.
git pull
. J'ai trouvé un bogue dans l'opérande de gauche qui ne s'est pas correctement encapsulé.Réponses:
Résultat: 22120 (3414 octets)
Ma solution utilise une table de recherche de 3 Ko pour amorcer un solveur de méthode de Newton qui s'exécute pendant zéro à trois itérations en fonction de la taille du résultat.
la source
Résultat: 27462
Il était temps que je participe à un défi GOLF : D
la source
Résultat: 161558
227038259038260038263068J'ai pris l'algorithme de racine carrée entier le plus rapide que j'ai pu trouver et retourner si son reste est zéro.
EDIT 1: suppression du test de quadrature, retournez! Le reste directement, économisez 3 opérations par test
EDIT 2: utilisez n comme le reste directement, économisez 1 op par test
EDIT 3: simplification de la condition de boucle, économie de 32 opérations par test
EDIT 4: déroulé la boucle, économisez environ 65 opérations par test
la source
0x4000000000000000
comme1 << 62
:)Résultat: 344493
Effectue une simple recherche binaire dans l'intervalle
[1, 4294967296)
à approximersqrt(n)
, puis vérifie s'iln
s'agit d'un carré parfait.la source