Tableau de bord
Voici les scores bruts (c.-à-d. Le nombre de dominos) pour la soumission de VisualMelon. Je transformerai ces résultats en les scores normalisés décrits ci-dessous, lorsque davantage de réponses entreront. La solution existante peut maintenant résoudre tous les circuits de la référence:
Author Circuit: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
VisualMelon 39 45 75 61 307 337 56 106 76 62 64 62 182 64 141 277 115 141 92 164 223 78 148 371 1482 232 107 782 4789 5035 1314 3213 200 172 1303 3732 97596 156889 857
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Legend:
I - invalid circuit
B - circuit too big
W - circuit computes wrong function
T - exceeded time limit
Le défi
Il est possible de construire des portes logiques simples à partir de dominos. Par conséquent, en combinant ces éléments ou autrement, des fonctions binaires arbitraires peuvent être calculées avec des dominos.
Mais bien sûr, tous ceux qui ont joué avec des dominos (à l'exception de Robin Paul Weijers) ont connu la déception lorsqu'ils en ont manqué. Par conséquent, nous voulons utiliser nos dominos aussi efficacement que possible afin de pouvoir effectuer des calculs vraiment intéressants avec le matériel dont nous disposons.
Notez que vous ne pouvez pas produire de sortie non nulle à partir d'une entrée zéro en tant que telle. Nous aurons donc besoin d'ajouter une "ligne d'alimentation" qui correspond à votre configuration et sur laquelle vous pouvez extraire 1
à tout moment.
Ta tâche
Étant donné une fonction booléenne avec des M
entrées et des N
sorties ( f: {0,1}^M --> {0,1}^N
pour les inclinés mathématiquement), créez un circuit domino avec le moins de dominos possible pour calculer cette fonction. Vous allez utiliser les symboles |
, -
, /
, \
pour représenter dominos dans diverses orientations.
Contribution
Vous aurez une entrée via des arguments en ligne de commande:
[command for your solver] M N f
où M
et N
sont des entiers positifs et f
est la table de vérité séparée par des virgules dans l'ordre canonique. C'est-à-dire, f
contiendra des 2^M
valeurs de longueur N
. Par exemple, si M = N = 2
et le premier bit de la sortie était la fonction AND alors que le deuxième bit était la fonction OR, f
lirait
00,01,01,11
Sortie
Écrivez à STDOUT une grille ASCII représentant la configuration du domino. Votre configuration doit s’inscrire dans le cadre suivant
/////.../////
????...????
I????...????O
I????...????O
.............
.............
I????...????O
I????...????O
I????...????O
- La rangée supérieure est entièrement constituée de
/
, et le domino le plus à gauche est sûr d’être renversé au début - c’est votre ligne électrique. - La colonne la plus à gauche est constituée de vos entrées. Chacun
I
peut être un espace ou un|
, de sorte qu'il existe exactementM
|
s. - La colonne la plus à droite est constituée de vos sorties. Chacun
O
peut être un espace ou un|
, de sorte qu'il y a exactementN
|
s. - Notez qu'il y a au moins un blanc avant le premier
|
en entrée ou en sortie. - Les
.
indiquent que la grille peut être arbitrairement grande. - Vous pouvez remplir
?
comme vous le souhaitez.
Notez que l'entrée du bas est la plus rapide, tandis que l'entrée du haut correspond 0
à la première moitié des sorties et 1
à la seconde moitié.
Règles
Les dominos se propagent comme spécifié dans Golfing for Domino Day . En bref, si nous représentons les directions en baisse sous forme de lettres
Q W E
A D
Z X C
alors ce sont toutes des combinaisons uniques qui peuvent se propager (ainsi que leurs rotations et leurs réflexions):
D| -> DD D\ -> DE D/ -> DC
C| -> CD C/ -> CC
C -> C C -> C C -> C
| D - X / C
Toutes les règles ci-dessus sont appliquées simultanément à chaque pas de temps. Si deux de ces règles sont en conflit (c'est-à-dire qu'une tuile est poussée simultanément dans deux directions valides opposées), la tuile affectée ne tombera pas et sera effectivement verrouillée pour le reste de la simulation.
Restrictions
M
etN
ne dépassera jamais 6.- Votre solveur doit produire un circuit dans un délai de N * 2 M secondes .
- Votre solveur ne doit pas utiliser plus de 1 Go de mémoire . C'est une limite souple, car je vais surveiller cela manuellement et tuer votre processus s'il dépasse cette limite de manière significative / continue.
- Aucun circuit n'est autorisé à contenir plus de 8 000 000 cellules ou 1 000 000 de dominos .
- Votre soumission doit être déterministe . Vous êtes autorisé à utiliser des générateurs de nombres pseudo-aléatoires, mais ils doivent utiliser une graine codée en dur (que vous êtes libre d'optimiser autant que vous le souhaitez).
Notation
Pour chaque circuit, prenons D
le nombre total de dominos dans votre circuit et B
le nombre le plus bas de dominos avec lesquels ce circuit a été résolu (par vous ou tout autre participant). Ensuite, votre score pour ce circuit est donné par 10,000 * B / D
arrondi. Si vous ne parvenez pas à résoudre le circuit, votre score est égal à 0. Votre score global correspond à la somme d'un ensemble de tests de référence. Les circuits qui n'ont pas encore été résolus par quiconque ne seront pas inclus dans le score total.
Chaque participant peut ajouter un cas de test à la référence (et toutes les autres soumissions seront réévaluées, y compris le nouveau cas de test).
Le fichier de référence se trouve sur GitHub .
Exemples
Voici quelques exemples résolus de manière non optimale.
Constante 1
1 1
1,1
///////
/
| |||
Nombre de domino: 12
Porte OU
2 1
0,1,1,1
///////////
|||||/
|||||
|||||\
Nombre de domino: 28
ET porte
2 1
0,0,0,1
///////////////////
\-/
- -
|||||/|\ /|||/
/ -
- \-
\- \ -
|||||\ / \ /
|\ |||||
Nombre de domino: 62
Échanger des voies
2 2
00,10,01,11
////////////
||||/ \||||
/\
\/
||||\ /||||
Nombre de domino: 36
Notes complémentaires
Les règles de propagation sont telles que les voies en diagonale peuvent se croiser en utilisant la forme d’un losange (voir dernier exemple), même si l’une tombe avant l’autre (contrairement aux vrais dominos).
Comme point de départ, vous pouvez utiliser les portes logiques (non minimisées) de cet élément et essayer de combiner le moins possible. Pour un moyen simple (non optimal) de créer des fonctions booléennes arbitraires à partir des portes AND, OR et NOT, examinez les formes normales conjonctives et disjonctives .
Il existe un vérificateur dans ce référentiel GitHub pour tester votre code, qui sera également utilisé pour noter toutes les soumissions. Cela génère les scores bruts (comptes de dominos) et les enregistre dans un fichier qui sera traité par un marqueur distinct (également dans ce référentiel) pour obtenir les scores finaux.
La documentation générale se trouve dans les deux fichiers Ruby, mais il controller.rb
faut deux commutateurs de ligne de commande avant le fichier de référence:
-v
vous donne plus de sortie, y compris les circuits réels produits par votre solveur.-c
vous permet de sélectionner un sous-ensemble du point de référence que vous souhaitez tester. Fournissez les circuits souhaités sous forme de liste d’indices à base 1 séparés par des virgules. Vous pouvez également utiliser les gammes Ruby pour pouvoir faire quelque chose comme-c 1..5,10,15..20
.
S'il vous plaît inclure dans votre réponse:
- Votre code
- Une commande pour (compiler et) exécuter votre code. Je vous demanderai où trouver les compilateurs / interprètes nécessaires si je ne les ai pas.
- Une table de vérité supplémentaire avec un nom, à ajouter comme cas de test à la référence. (Ceci est facultatif, mais fortement encouragé.)
Je vais tester toutes les soumissions sur Windows 8.
la source
Réponses:
C # - Solution massive, lente et inefficace
Confession: a écrit cette solution il y a quelque temps alors que la question était encore dans le bac à sable, mais ce n'est pas très bon: vous pouvez faire mieux!
Edit: a remplacé la résolution ennuyeuse par une méthode moins ennuyeuse, plus flexible et généralement meilleure
Vous exécutez le programme en compilant avec
csc dominoPrinter.cs
, puis en transmettant des arguments à l'exécutable, par exemple (le vérificateur principal 4 bits):Explication:
"Imprimante Domino" est un programme en 3 étapes:
Étape 1 : Le "résolveur" génère un arbre d'expression d'opérations "ifnot" et "ou" avec les entrées indiquées, et un "1" à partir de la ligne à haute tension.
S'il y a moins de 4 entrées, le programme propose une solution du plus petit nombre possible d'opérations.
S'il y a 4 entrées ou plus, le programme brute chaque bloc de sortie de 8 bits, puis combine les résultats pour donner le résultat souhaité. Les bits brutés sont flexibles: plus les bits sont brutes, plus la solution est petite, mais plus le temps d'exécution est long.
Le "résolveur" est ce qui prend tout le temps (ou du moins ce qu’il avait l'habitude de faire), et c'est aussi l'essentiel du code. Je crois qu’il existe une solution bien documentée, rapide, pas très gourmande en mémoire, et probablement optimale à ce problème, mais quel serait le plaisir de le rechercher?
L'arbre d'expression (brute) du vérificateur principal 4 bits est
où les nombres sont les index des entrées.
Etape 2 : "l'organisateur" prend l'arbre d'expression en tant qu'entrée et assemble une présentation "squelette", qui décrit précisément une présentation en domino constituée d'un ensemble de cellules se chevauchant 4x5. Vous trouverez ci-dessous le squelette du vérificateur principal 4 bits bruté (vous devez modifier la
bruteBase
variable entière de la ligne 473 en 4 (ou plus) pour obtenir ce résultat).Cette sortie est composée de deux parties, l’évaluateur à droite, créé à partir de l’arbre d’expressions de l’étape 1, et le "tableau" à gauche, qui permute et divise les entrées afin qu’elles arrivent dans la bons endroits pour "l'évaluateur" à gérer.
Il existe une marge considérable pour compacter la mise en page à ce stade, mais le programme effectue actuellement très peu ce travail. Le code pour cette étape est horrible, mais assez simple en dessous (voir la méthode "orifnot"). La sortie est transmise à l'étape 3.
Etape 3 : "L'imprimante" prélève la sortie de "l'organisateur" et imprime les "cellules" 4x5 correspondantes se chevauchant avec la ligne d'alimentation. Vous trouverez ci-dessous une animation du vérificateur d’amorce de 4 bits brute vérifiant si 5 est premier.
Code le manque d'indentation est d'éviter de dépasser la limite de caractères SE 30k qu'il serait autrement :
Un cas de test supplémentaire:
Ceci vérifie si deux bits adjacents (non enveloppants) sont des 1 (par exemple, vrai pour 0110, mais faux pour 0101 et 1001)
la source
I
et dont les sorties spécifient une nouvelle mise en page de domino