Les vignerons olympiques exécutent leurs routines dans des arbres standard. En particulier, l'arbre standard n
a des sommets pour le 0
haut n-1
et des bords reliant chaque sommet non nul a
au sommet en n % a
dessous. Ainsi, par exemple, l'arbre standard 5 ressemble à ceci:
3
|
2 4
\ /
1
|
0
parce que le reste lorsque 5 est divisé par 3 est 2, le reste lorsque 5 est divisé par 2 ou par 4 est 1, et le reste lorsque 5 est divisé par 1 est 0.
Cette année, Tarzan défendra son or avec de nouvelles routines, chacune commençant au sommet n - 1
, se balançant au sommet n - 2
, se poursuivant au sommet n - 3
, etc., jusqu'à ce qu'il finisse par descendre au sommet 0
.
Le score pour une routine est la somme des scores pour chaque swing (y compris le démontage), et le score pour un swing est la distance dans l'arbre entre ses points de début et de fin. Ainsi, la routine de Tarzan sur Standard Tree 5 a un score de 6:
- un swing de
4
à3
marque trois points (bas, haut, haut), - un swing de
3
à2
marque un point (vers le bas), - un swing de
2
à1
marque un point (vers le bas), et - un démontage de
1
à0
marque un point (vers le bas).
Écrivez un programme ou une fonction qui, étant donné un entier positif n
, calcule le score de la routine de Tarzan sur l'arbre standard n
. Exemples d'entrées et sorties:
1 -> 0
2 -> 1
3 -> 2
4 -> 6
5 -> 6
6 -> 12
7 -> 12
8 -> 18
9 -> 22
10 -> 32
11 -> 24
12 -> 34
13 -> 34
14 -> 36
15 -> 44
16 -> 58
17 -> 50
18 -> 64
19 -> 60
20 -> 66
21 -> 78
22 -> 88
23 -> 68
24 -> 82
Les règles et la notation de code sont comme d'habitude pour le golf de code .
la source
Réponses:
C,
9897 octetsCela calcule la distance entre chaque paire de points avec la formule suivante:
Cela a l'avantage que lorsqu'il est appliqué à toutes les paires, c'est la même chose que:
Pour simplifier la logique, nous supposons que nous allons du nœud 0 au nœud n-1, plutôt que de n-1 à 0 comme l'indique la question. La distance du nœud racine au nœud 0 est évidemment 0 (ils sont les mêmes). Et nous pouvons voir que pour (la plupart) des arbres, la distance entre le dernier nœud et la racine est de 2:
Cela signifie que nous avons quelques cas particuliers (n <2) mais nous pouvons les prendre en compte assez facilement.
Panne:
Merci @feersum pour 1 octet enregistré
Bonus: des arbres!
J'ai écrit un programme rapide et sale pour voir à quoi ressemblent ces arbres. Voici quelques résultats:
19:
la source
Python 2, 85 octets
la source
Perl,
65595554 octetsComprend +2 pour
-ap
Exécutez avec la taille de l'arbre sur STDIN:
vines.pl
:Explication
Si vous réécrivez l'arbre
à un où chaque nœud contient l'ensemble de tous ses ancêtres et lui-même:
Ensuite, nous pouvons décrire par exemple tous les nœuds le chemin de 4 à 3 comme:
Le nombre d'arêtes est inférieur de un au nombre de nœuds afin que nous puissions l'utiliser pour ignorer le point de jointure, donc le nombre d'arêtes sur le chemin de 4 à 3 est 3 car:
Notez que cela fonctionne également pour un chemin qui descend directement vers sa cible, par exemple pour le chemin de 3 à 2, le nombre d'arêtes est 1 car:
On peut alors additionner toutes ces combinaisons.
Si vous regardez plutôt un nœud, par exemple le nœud 2 avec un ensemble d'ancêtres
{2,3}
. Ce nœud va contribuer une fois lors du traitement du chemin2 to 1
car il contient un 2 mais pas un 1. Il ne contribuera rien pour le chemin3 to 2
car il a à la fois 2 et 3, mais il contribuera une fois lors du traitement du chemin4 to 3
car il en a 3 mais non 4. En général, un nombre dans l'ensemble des ancêtres d'un nœud contribuera à un pour chaque voisin (un inférieur ou supérieur) qui n'est pas dans l'ensemble. Sauf pour l'élément maximum (4 dans ce cas) qui ne contribue que pour le voisin bas 3 car il n'y a pas de chemin5 to 4
. Le 0 simulaire est unilatéral, mais puisque 0 est toujours à la racine de l'arbre et contient tous les nombres (c'est la jointure ultime et nous ne comptons pas les jointures), il n'y a jamais de contribution de 0, il est donc plus facile de simplement quitter le nœud 0 tout à fait.Nous pouvons donc également résoudre le problème en examinant l'ensemble d'ancêtres pour chaque nœud, compter les contributions et additionner tous les nœuds.
Pour traiter facilement les voisins, je vais représenter les ensembles d'ancêtres sous la forme d'une chaîne d'espaces et de 1 où chaque 1 à la position p représente que n-1-p est un ancêtre. Ainsi, par exemple, dans notre cas d'
n=5
un 1 à la position 0, 4 indique un ancêtre. Je laisserai de côté les espaces de fuite. La représentation réelle de l'arbre que je vais construire est donc:Notez que j'ai omis le nœud 0 qui serait représenté par
"11111"
car je vais ignorer le nœud 0 (il ne contribue jamais).Les ancêtres sans voisin inférieur sont maintenant représentés par la fin d'une séquence de 1. Les ancêtres sans voisin supérieur sont maintenant représentés par le début d'une séquence de 1, mais nous devons ignorer tout début d'une séquence au début d'une chaîne car cela représenterait le chemin
5 to 4
qui n'existe pas. Cette combinaison correspond exactement à l'expression régulière/.\b/
.La construction des chaînes ancêtres se fait en traitant tous les nœuds dans l'ordre
n-1 .. 1
et en définissant un 1 à la position du nœud lui-même et en faisant un "ou" dans le descendant.Avec tout cela, le programme est assez facile à comprendre:
Notez que le remplacement
/.\b/
par/\b/
résout la version aller-retour de ce problème où tarzan prend également le chemin0 to n-1
Quelques exemples de l'apparence des chaînes ancêtres (données dans l'ordre
n-1 .. 1
):la source
Mathematica,
113103102 octets-10 octets grâce à @feersum; -1 octet grâce à @MartinEnder
Ce qui suit est beaucoup plus rapide (mais plus long, malheureusement, à 158 octets ):
la source
With
. De plus, il semble que chaque fois qu'ilRange
est utilisé,a
c'est l'argument, qui pourrait donc être pris en compte.r=Range[a=#-1]
enregistre un octet.J, 37 octets
Usage:
Essayez-le en ligne ici.
la source
JavaScript (ES6),
118116 octetsLe manque d'une fonction de différence définie fait vraiment mal, mais une récursivité créative réduit un peu le nombre d'octets. Edit: enregistré 2 octets en supprimant un paramètre inutile.
la source