Supposons que nous définissions une matrice infinie M
, sur N^2 -> {0, 1}
(où N
commence à la 1
place de 0
) de cette manière:
M(1, 1)
=0
.Pour tout
x > 1
,M(x, 1)
=1
ifx
est premier, et0
sinon.Pour chaque
y > 1
,M(1, y)
= ley
e terme duThue-Morse sequence
.Pour chaque
x, y > 1
,M(x, y)
=M(x, y-1) + M(x-1, y) mod 2
.
La section en haut à gauche 16x16
de cette matrice ressemble (avec des x
lignes et des y
colonnes):
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1
1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 0
0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1
1 0 1 1 0 0 1 0 1 0 1 1 1 1 0 1
0 0 1 0 0 0 1 1 0 0 1 0 1 0 0 1
1 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1
0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1
0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1
0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 0
1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1
0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 1
1 1 0 0 1 0 1 1 0 1 1 1 0 1 1 0
0 1 1 1 0 0 1 0 0 1 0 1 1 0 1 1
0 1 0 1 1 1 0 0 0 1 1 0 1 1 0 1
0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 1
Votre tâche consiste à créer un programme qui évaluera la valeur d'une entrée arbitraire dans cette matrice aussi précisément que possible.
Votre programme prendra deux entiers x
et y
en entrée, sous la forme que vous choisirez, et retournera M(x, y)
, qui sera soit 0
ou 1
.
Votre code peut être écrit dans n'importe quelle langue, mais ne doit pas dépasser 64 kilo-octets (65 536 octets) de taille de code source ou 2 Mo (2 097 152 octets) d'utilisation totale de la mémoire. Votre programme doit démarrer avec une mémoire vide (c'est-à-dire qu'il ne peut pas charger de données ailleurs) et s'exécuter indépendamment pour chaque entrée (c'est-à-dire qu'il ne peut pas stocker de données communes pour plusieurs exécutions). Votre programme doit également être en mesure d'évaluer toutes les entrées du 8192x8192
carré supérieur gauche dans un délai raisonnable.
Le programme qui évalue correctement le plus d'entrées dans le 8192 x 8192
carré supérieur gauche sera le gagnant, avec un code plus court faisant office de bris d'égalité.
la source
Réponses:
J -
4238 carAssez rapide, 100% précis et bien dans les contraintes de mémoire.
La stratégie est la suivante: nous allons calculer les antidiagonales successives de cette matrice, en effectuant un XOR par paire pour avancer et en ajoutant les bits Thue-Morse et Prime actuels aux extrémités. Nous retirons ensuite le chiffre requis de l'antidiagonale lorsque nous y arrivons.
Explication par explosion:
L'utilisation de ce verbe est
x m y
pour M (x, y) comme spécifié dans la question, oùm
est le verbe.Pour enregistrer les frappes, nous n'essayons pas de dire si nous avons encore besoin de bits principaux ou Thue-Morse, nous calculons donc toute l'antidiagonale pour obtenir le bit que nous voulons. Cependant,
8192 m 8192
fonctionne toujours en moins de 0,07 s et environ 100 Ko sur mon modeste ordinateur portable.la source
Mathematica - 100% de précision,
223193189 octetsVoici une version lisible:
Je calcule essentiellement le long de diagonales de constante
x+y
.Fonctionnalités:
O(x*y)
.f[8192,8192]
prend environ 400 secondes. Je suppose qu'il y a place à amélioration (peutRotateLeft
- être pourrait remplacer la boucle intérieure).Il utilise uniquement un tableau de
max(x,y)
résultats jusqu'à intermédiaires dans la mémoire. Il n'est donc pas nécessaire d'utiliser plus d'environ 32k (en supposant des entiers 32 bits) pour l'algorithme lui-même (plus, quoi que Mathematica utilise). En fait, Mathematica utilise 31M seul sur mon système, mais cela fonctionne sans problème:la source
O(x*y)
temps, mais le temps d'exécution total augmente plus rapidement que cela. Je ne sais pas trop ce qui se passe. Si certains Mathematica Guru pouvaient m'éclairer, quelle opération dans la boucle neO(1)
serait pas très utile! :) (eh bien,PrimeQ
etTotal@IntegerDigits
ne le sont pas, mais je les ai depuis le début, et ils n'ont appelé queO(y)
etO(x)
respectivement)Matlab: 100% de précision, 120 caractères, temps d'exécution déraisonnable
Utiliser:
la source
M(8192, 8192)
, je ne peux pas le supporter.Python, 192 caractères
100% de précision, calcule M (8192 8192) en ~ 10 secondes sur ma machine.
la source
Haskell - 261 octets - 100% - 1 Mo - Je ne pense pas que ça va se terminer de sitôt
Prend environ 10 secondes pour
m 16 16
avec-O2
, mais comme je l'ai écrit de toute façon, je peux le montrer malgré ce problème:Peut-être qu'un bon Haskeller est capable de l'optimiser?
la source
f p|p=not|0<1=id
devrait aussi être mieux. essayez également de l'utilisermorse = False : concat $ iterate [True] (\a -> a ++ map not a)
pour augmenter la paresse. Je me demande comment cela affectera les performances.True
au golf vers0<1
etFalse
vers0>1
.Perl, 137
Pas pour «gagner» :-), mais comme il n'y a pas encore de Perl ici et que le code a quand même été écrit, le voici.
Prend plusieurs secondes s'il est appelé
print f(8192,8192)
, stocke une seule ligne de matrice en mémoire (tableau de 8192 entiers (scalaires)), soit environ 3,5 Mo de processus Perl. J'ai essayé de le faire avec une chaîne au lieu d'un tableau (soit avec des expressions rationnelles ou en accédant avec substr), prend moins de mémoire et peut être joué plus loin, mais fonctionne beaucoup plus lentement.Dentelé:
la source
Haskell, 223
cela a un temps d'exécution rapide (5,7 secondes avec
-O3
). la mémoire n'a pas encore été vérifiée, bien qu'elle devrait être linéaire.cela utilise l'algorithme diagonal vu précédemment.
en ce qui concerne la vitesse, les seules choses qui importent sont l'algorithme diagonal
-O3
, et le|foldr seq(0>1)s=0<1
garde, ce qui rend la liste stricte. tout le reste est implémenté de manière assez inefficace - la vérification principale est effectuée en vérifiant tous les nombres inférieurs pour la division, les éléments de la séquence Morse sont recalculés en permanence. mais c'est quand même assez rapide :-).la source