Quanto sono forti i numeri non binari?


10

Ti viene dato un numero intero non negativo (base 9) composto dalle cifre da 0 a 8 come al solito. Tuttavia, il numero di cifre in questo numero (senza zeri iniziali) è un quadrato perfetto.

Per questo motivo, il numero può essere organizzato in una griglia quadrata (con l'ordine di lettura ancora conservato).

Esempio con 1480 (1125 base 10):

14
80

Ora lascia che ogni cifra in una griglia non binaria indichi un movimento verso un altro spazio della griglia (con condizioni al contorno periodiche ):

432
501
678

Questo sta dicendo questo

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

Quindi, se nella griglia del 1480 inizi dal 4, ti sposti in alto (ricorda pbc) e poi a sinistra verso l'8, il che significa che ti sposti a destra e in basso al 4, iniziando un ciclo con il periodo 2.

In generale questo processo continua fino a quando si arriva a 0 o si nota un ciclo. (Uno 0 è considerato un ciclo con il periodo 1)

Nel caso del 1480, il periodo eventualmente raggiunto in corrispondenza di ciascuna delle 4 cifre iniziali è 2 2 2 1rispettivamente.

Per una griglia più grande questi numeri potrebbero essere più grandi di 8, ma possiamo ancora usarli come "cifre" in un nuovo numero non reale (semplicemente i coefficienti di 9 ^ n come se fossero cifre):

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

Chiameremo questo il punto di forza del numero non nota originale. Quindi la forza di 1480 è 1639 (base 10) o, equivalentemente, 2221 (base 9).

Sfida

Scrivi il programma più breve che indichi se la forza di un numero non è maggiore di, minore di o uguale al numero non reale stesso. (Non è necessario calcolare necessariamente la forza.)

L'input sarà un numero nonary non negativo che contiene un numero quadrato di cifre (e nessuno zero iniziale oltre al caso speciale di 0 stesso). Dovrebbe venire dalla riga di comando o stdin.

L'output dovrebbe andare su stdout come:

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)

Divertente sfida bonus:
qual è l'input più alto che riesci a trovare uguale alla sua forza? (C'è un limite?)


Per quanto riguarda l'input, viene indicato come un numero decimale le cui cifre sono uguali al numero non binario o alla rappresentazione decimale (o binaria) del numero non binario? vale a dire: per 1480 (non) l'ingresso sarà 1480 o 1125?
overactor

@overactor In formato non binario.

2
Sono abbastanza fiducioso che nessuno troverà un input superiore che equivale alla sua forza di 10 ^ 71-1 (non), cioè un numero di 64 cifre che consiste solo di 8
overactor

@overactor Potrebbe essere possibile con cicli di periodo superiori a 8, credo.
Martin Ender,

@ MartinBüttner rimarrò profondamente colpito se ne trovi qualcuno.
overactor

Risposte:


2

Python 2, 213 209 202

Modifica: corto circuito rimosso, che a volte non è corretto. Vedi sotto.

(In gran parte) Lo stesso algoritmo di @KSab, ma fortemente giocato a 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)]

golf:

  • 213: Corto circuito, soluzione difettosa.

  • 209: prima soluzione funzionante.

  • 202: Combina le due ricerche di stringhe in una.

Modifica: mi sono appena reso conto che questo programma, e quindi anche quello di KSab, erano difettosi in quanto ignoravano le lunghezze del ciclo multidigit. Esempio di errore:

3117
2755
3117
7455

Mentre il 3 ha una durata del ciclo di 2, e quindi l'algoritmo sopra cortocircuita a "L", ciò dovrebbe in effetti restituire "G", poiché la lunghezza del ciclo di 14 sulla seconda cifra supera di gran lunga quella. Ho quindi modificato il programma. Inoltre è diventato più breve, abbastanza divertente. Per testare il programma, utilizzare 3117275531177455. Dovrebbe tornare G.


Wow, ho pensato di giocarci un po ', ma hai fatto cose abbastanza intelligenti lì.
KSab il

@KSab Grazie - il tuo algoritmo è stato molto intelligente all'inizio - non sono riuscito a trovare un modo migliore per farlo.
isaacg,

2

Python 296

In realtà non troppo inefficiente, controlla solo tutte le cifre necessarie.

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

Per quanto riguarda i numeri pari alla loro forza, penso che le uniche soluzioni siano, per ogni quadrato N x N fino a N = 8 un quadrato contenente N in ogni spazio. Il mio pensiero è che poiché ogni numero in un loop deve essere lo stesso numero (la lunghezza del loop) ogni loop dovrebbe essere tutto in una direzione. Questo ovviamente significa che la dimensione del loop deve essere N (e ogni elemento deve essere N). Sono abbastanza sicuro che questa logica possa essere applicata a quadrati e anelli di qualsiasi dimensione, il che significa che non ci sono quadrati uguali alla loro forza oltre ai primi 8.


Sebbene improbabile, potrebbe essere possibile per loop maggiori di 8.
overactor

2
Penso che questo dia il risultato sbagliato 3117275531177455, a causa delle dimensioni del loop superiori a 8. Vedi il mio post.
isaacg

1
@isaacg Oh, non l'ho visto, l'ho cambiato per farlo funzionare, ma non ho intenzione di provare a giocarlo ulteriormente perché sarebbe praticamente incollare la tua risposta. Oh e penso che puoi migliorare le tue ultime due righe usando cmp.
KSab,


0

Lua - Non ho ancora giocato a golf

Sto solo mettendo qui per la custodia. Lo giocherò (e implementerò "Per una griglia più grande questi numeri potrebbero essere più grandi di 8, ma possiamo ancora usarli come" cifre "") in seguito. Funziona però.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.