Quão fortes são os números nonary?

10

Você recebe um número inteiro não negativo não-primário (base 9) que consiste nos dígitos de 0 a 8, como de costume. No entanto, o número de dígitos nesse número (sem zeros à esquerda) é um quadrado perfeito.

Por esse motivo, o número pode ser organizado em uma grade quadrada (com a ordem de leitura ainda preservada).

Exemplo com 1480 (1125 base 10):

14
80

Agora, permita que cada dígito em uma grade nonary indique um movimento para outro espaço da grade (com condições de contorno periódicas ):

432
501
678

Isso está dizendo que

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

Portanto, se na grade 1480 você começa no 4, você move para cima (lembre-se pbc) e sai para o 8, o que significa que você move para a direita e para baixo de volta para o 4, iniciando um ciclo com o período 2.

Em geral, esse processo continua até que você chegue a um 0 ou um ciclo seja notado. (A 0 é considerado um ciclo com o período 1.)

No caso de 1480, o período finalmente alcançado em cada um dos 4 dígitos iniciais é 2 2 2 1respectivamente.

Para uma grade maior, esses números podem ser maiores que 8, mas ainda podemos usá-los como "dígitos" em um novo número não-primário (simplesmente os coeficientes de 9 ^ n como se fossem dígitos):

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

Nós chamaremos isso de força do número nonary original. Portanto, a força de 1480 é 1639 (base 10) ou, equivalentemente, 2221 (base 9).

Desafio

Escreva o programa mais curto que diga se a força de um número não-primário é maior que, menor que ou igual ao número não-próprio. (Você não precisa necessariamente calcular a força.)

A entrada será um número nonary não negativo que contém um número quadrado de dígitos (e nenhum zero inicial além do caso especial de 0). Deve vir da linha de comando ou stdin.

A saída deve ir para stdout como:

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)

Desafio de bônus divertido:
Qual é a maior contribuição que você pode encontrar que é igual à sua força? (Existe um limite?)


fonte
Quanto à entrada, ela é fornecida como um número decimal cujos dígitos são iguais ao número não-numerário ou à representação decimal (ou binária) do número não-numerário? ou seja: para 1480 (não) a entrada será 1480 ou 1125?
overactor
@overactor No formato não primário.
2
Estou bastante confiante de que ninguém vai encontrar uma entrada maior que é igual a sua força de 10 ^ 71-1 (não) isto é, um número de 64 dígitos que consiste apenas de 8 de
overactor
@overactor Pode ser possível com ciclos de período maiores que 8, eu acho.
Martin Ender
@ MartinBüttner ficarei muito impressionado se você encontrar algum deles.
overactor

Respostas:

2

Python 2, 213 209 202

Editar: Removido o curto-circuito, que às vezes está incorreto. Ver abaixo.

(Em grande parte) O mesmo algoritmo que o @KSab, mas com muita intensidade.

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)]

Golfe:

  • 213: Solução defeituosa em curto-circuito.

  • 209: Primeira solução de trabalho.

  • 202: Combinou as duas pesquisas de sequência em uma.

Edit: Acabei de perceber que este programa e, portanto, o KSab também eram defeituosos, pois ignoravam os comprimentos do ciclo de vários dígitos. Falha de exemplo:

3117
2755
3117
7455

Enquanto o 3 tem um comprimento de ciclo de 2 e, portanto, o algoritmo acima curto-circunda para 'L', isso deve de fato retornar 'G', porque o comprimento de ciclo de 14 no segundo dígito supera isso. Eu, portanto, mudei o programa. Também ficou mais curto, curiosamente. Para testar seu programa, use 3117275531177455. Deve retornar G.

isaacg
fonte
Uau, eu pensei em jogar um pouco, mas você fez algumas coisas bem inteligentes por lá.
precisa saber é
@KSab Obrigado - seu algoritmo era muito inteligente para começar - não consegui encontrar uma maneira melhor de fazê-lo.
Isaacg
2

Python 296

Na verdade, não é muito ineficiente, apenas verifica quantos dígitos é necessário.

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))]

Quanto aos números iguais à sua força, acho que as únicas soluções são: para cada quadrado N x N até N = 8 um quadrado contendo N em todos os espaços. Meu pensamento é que, já que todo número em um loop deve ter o mesmo número (o comprimento do loop), cada loop deve estar todo em uma direção. Obviamente, isso significa que o tamanho do loop deve ser N (e cada elemento deve ser N). Tenho certeza de que essa lógica pode ser aplicada a quadrados e loops de qualquer tamanho, o que significa que não há quadrados iguais à sua força além dos 8 primeiros.

KSab
fonte
Embora improvável, pode ser possível para loops maiores que 8.
overactor
2
Eu acho que isso dá o resultado errado 3117275531177455, por causa de tamanhos de loop maiores que 8. Veja meu post.
Isaacg
11
@isaacg Oh, eu não vi isso, mudei para dar certo, mas não vou tentar jogar mais, porque isso seria apenas copiar e colar sua resposta. Ah, e acho que você pode melhorar suas duas últimas linhas usando cmp.
KSab
1

CJam - 81

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

Experimente em http://cjam.aditsu.net/

Provavelmente pode ser jogado um pouco mais.

aditsu sair porque SE é MAU
fonte
0

Lua - Ainda não jogou golfe

Apenas colocando aqui por segurança. Vou jogar golfe (e implementar o "Para uma grade maior, esses números podem ser maiores que 8, mas ainda podemos usá-los como" dígitos "") posteriormente. Funciona embora.

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
fonte