Quelle est la force des nombres nonaires?

10

On vous donne un entier non négatif (base 9) non négatif composé des chiffres de 0 à 8 comme d'habitude. Cependant, le nombre de chiffres de ce nombre (sans zéros de tête) est un carré préfet.

Pour cette raison, le nombre peut être organisé dans une grille carrée (avec l'ordre de lecture toujours préservé).

Exemple avec 1480 (1125 base 10):

14
80

Maintenant, laissez chaque chiffre dans une telle grille nonaire indiquer un mouvement vers un autre espace de la grille (avec des conditions aux limites périodiques ):

432
501
678

Cela veut dire que

0 = stay still
1 = move right
2 = move right and up
3 = move up
...
8 = move right and down

Donc, si dans la grille 1480 vous commencez au 4, vous montez ensuite (rappelez-vous pbc) et à gauche au 8, ce qui signifie que vous vous déplacez à droite et en bas vers le 4, en commençant un cycle avec la période 2.

En général, ce processus se poursuit jusqu'à ce que vous atteigniez un 0 ou qu'un cycle soit remarqué. (A 0 est considéré comme un cycle avec la période 1.)

Dans le cas de 1480, la période finalement atteinte à chacun des 4 chiffres de départ est 2 2 2 1respectivement.

Pour une grille plus grande, ces nombres peuvent être supérieurs à 8, mais nous pouvons toujours les utiliser comme "chiffres" dans un nouveau nombre nonaire (simplement les coefficients de 9 ^ n comme s'il s'agissait de chiffres):

2*9^3 + 2*9^2 + 2*9 + 1 = 1639 (base 10) = 2221 (base 9)

Nous appellerons cela la force du nombre nonaire d'origine. La force de 1480 est donc 1639 (base 10) ou, de manière équivalente, 2221 (base 9).

Défi

Écrivez le programme le plus court qui indique si la force d'un nombre nonaire est supérieure, inférieure ou égale au nombre nonaire lui-même. (Vous n'avez pas nécessairement besoin de calculer la force.)

L'entrée sera un nombre nonaire non négatif qui contient un nombre carré de chiffres (et pas de zéros non significatifs à part le cas spécial de 0 lui-même). Il doit provenir de la ligne de commande ou de stdin.

La sortie devrait aller à stdout comme:

G if the strength is larger than the original number (example: 1480 -> strength = 2221)
E if the strength is equal to the original number (example: 1 -> strength = 1)
L if the strength is less than the original number (example: 5 -> strength = 1)

Fun Bonus Challenge:
Quelle est la plus grande contribution que vous pouvez trouver qui est égale à sa force? (Y a-t-il une limite?)


la source
Quant à l'entrée, est-elle donnée sous forme de nombre décimal dont les chiffres sont les mêmes que le nombre nonaire ou comme représentation décimale (ou binaire) du nombre nonaire? ie: pour 1480 (non) l'entrée sera-t-elle 1480 ou 1125?
suracteur
@overactor Au format nonaire.
2
Je suis assez confiant que personne ne trouvera une entrée plus élevée qui équivaut à sa force que 10 ^ 71-1 (non), c'est-à-dire un nombre à 64 chiffres qui se compose uniquement de 8
suracteur
@overactor Cela pourrait être possible avec des cycles de période supérieurs à 8, je pense.
Martin Ender
@ MartinBüttner je serai très impressionné si vous en trouvez.
suracteur

Réponses:

2

Python 2, 213 209 202

Modifier: suppression des courts-circuits, ce qui est parfois incorrect. Voir ci-dessous.

(En grande partie) Le même algorithme que @KSab, mais très fortement golfé.

n=`input()`
s=int(len(n)**.5)
c=0
for i in range(s*s):
 a=[]
 while(i in a)<1:a+=[i];x='432501678'.find(n[i]);i=(i+x%3-1)%s+((i/s+x/3-1)%s)*s
 c=c*9+len(a)-a.index(i)
d=long(n,9)
print'EGL'[(c>d)-(c<d)]

Golfs:

  • 213: Solution défectueuse en court-circuit.

  • 209: Première solution de travail.

  • 202: Combiné les deux recherches de chaîne en une seule.

Edit: Je viens de réaliser que ce programme, et donc KSab aussi, étaient défectueux en ce qu'ils ignorent les longueurs de cycle à plusieurs chiffres. Exemple d'échec:

3117
2755
3117
7455

Alors que le 3 a une longueur de cycle de 2, et donc l'algorithme ci-dessus court-circuite à «L», cela devrait en fait retourner «G», car la longueur de cycle de 14 sur le deuxième chiffre dépasse largement cela. J'ai donc changé de programme. Il est également devenu plus court, assez drôle. Pour tester votre programme, utilisez 3117275531177455. Il devrait revenir G.

isaacg
la source
Wow, je pensais l'avoir assez bien joué au golf, mais vous y avez fait des trucs assez intelligents.
KSab
@KSab Merci - votre algorithme était très intelligent pour commencer - je ne pouvais pas trouver de meilleure façon de le faire.
isaacg
2

Python 296

Pas vraiment trop inefficace, il ne vérifie que le nombre de chiffres dont il a besoin.

n=raw_input();s=int(len(n)**.5);t=0
for i in range(s**2):
    l=[]
    while i not in l:l.append(i);c=n[i];i=(i%s+(-1 if c in'456'else 1 if c in'218'else 0))%s+((i/s+(-1 if c in'432'else 1 if c in'678'else 0))%s)*s
    t=t*9+len(l)-l.index(i)
print'EGL'[cmp(t,long(n,9))]

Quant aux nombres égaux à leur force, je pense que les seules solutions sont, pour chaque N x N carré jusqu'à N = 8 un carré contenant N dans chaque espace. Ma pensée est que puisque chaque nombre dans une boucle doit être le même nombre (la longueur de la boucle), chaque boucle devrait être dans une seule direction. Cela signifie bien sûr que la taille de la boucle doit être N (et chaque élément doit être N). Je suis à peu près sûr que cette logique peut être appliquée aux carrés et aux boucles de toute taille, ce qui signifie qu'il n'y a pas de carrés égaux à leur force autre que les 8 premiers.

KSab
la source
Bien que peu probable, il pourrait être possible pour des boucles de plus de 8.
suracteur
2
Je pense que cela donne le mauvais résultat 3117275531177455, en raison de la taille des boucles supérieures à 8. Voir mon article.
isaacg
1
@isaacg Oh, je ne l'ai pas vu, je l'ai changé pour le faire fonctionner, mais je ne vais pas essayer de le jouer davantage car ce serait à peu près copier-coller votre réponse. Oh et je pense que vous pouvez améliorer vos deux dernières lignes en utilisant cmp.
KSab
1

CJam - 81

q:X,:L,{[L2*{_[_Lmqi:Smd@X=432501678s#3md]2/z{~+(S+S%}%Sb}*]L>_&,\X=~-}%9bg"EGL"=

Essayez-le sur http://cjam.aditsu.net/

Il peut probablement être joué au golf un peu plus.

aditsu quitte parce que SE est MAL
la source
0

Lua - Pas encore joué au golf

Je mets juste ici pour la garde. Je vais le jouer (et implémenter le "Pour une plus grande grille, ces nombres peuvent être supérieurs à 8, mais nous pouvons toujours les utiliser comme" chiffres "") plus tard. Fonctionne cependant.

d={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}}
d[0]={0,0}ssd=''
n=arg[1]
q=math.sqrt(#n)t={}

    for y=1,q do
    table.insert(t,y,{})
    for x =1,q do
        v=(y-1)*q+x
        table.insert(t[y],x,n:sub(v,v)+0)
        io.write(t[y][x])
    end
end
for y=1,q do
    for x=1,q do
        cx=x cy=y pxy=''sd=0
        while pxy:match(cx..':%d*:'..cy..' ')==nil do
            pxy=pxy..cx..':'..sd..':'..cy.." "
            ccx=cx+d[t[cx][cy]][2]
            ccy=cy+d[t[cx][cy]][1]
            cx=ccx cy=ccy
            if cx<1 then cx=q elseif cx>q then cx=1 end
            if cy<1 then cy=q elseif cy>q then cy=1 end
            sd=sd+1
        end
        dds=(pxy:sub(pxy:find(cx..':%d+:'..cy)):match(':%d*'))
        ssd=ssd..(sd-dds:sub(2))
    end
end
print(ssd)
nn=tonumber(n,9) tn=tonumber(ssd,9)
if tn>nn then print("G") elseif tn==nn then print("E") else print("L") end
AndoDaan
la source