Olá Luan e Romário:
Primeiramente, Luan, o algoritmo que o Romário publicou deveria funcionar da seguinte forma:
O for externo é responsável por caminhar em um array preenchendo as posições com valores randômicos, entre 1 e 60.
Já o for interno é responsável por fazer uma verificação invertida de todos os valores da posição atual de i (seja essa qual for) até a posição inicial do vetor. Ao fazer isso, ele verifica se o número gerado é igual à algum numero já existente no array e, caso o mesmo seja, gera um número novo que, após a verificação, será inserido na posição atual de i.
Vamos ilustrar da seguinte forma:
i = 4. Ou seja, estamos na posição 3 do nosso vetor. Na realização do segundo for, o n vai receber 3 (i - 1) e será feita uma verificação entre o valor presente na posição 3 do array e o número (que foi gerado aleatoriamente). Caso o valor na posição 3 seja igual ao gerado, o algoritmo gera um novo número e volta uma posição no array e continua fazendo as verificações (aqui encontramos um problema que vou discorrer sobre mais a frente) até chegar à primeira posição. Assim que o loop termina, ele insere o elemento na posição i (que é a posição do array em que estávamos originalmente).
Quanto à sua dúvida " Eu não estaria a tentar acessar uma posição inexistente do array" - não. Lembre-se que o segundo elemento do for é um verificador. No for que o Romário utilizou, ele verifica se n é maior ou igual à zero. Caso i seja 0, n passa a ser -1 e não é aceito no verificador. Logo, o for interno não inicia e o for externo avança.
Agora, para os dois. Primeiramente, gerar uma sequência de números não repetidos com o uso de um PRNG não é uma tarefa exatamente fácil (especialmente se o intervalo for pequeno). Há de se considerar o seguinte: apesar de as chances de números repetidos acontecerem serem pequenas para um PRNG, o fato de utilizarmos a função floor (arrendondando para baixo) e termos um limite de 60 números, faz com que essa chance seja alta. Qual seria a solução? Verificar valor por valor e, caso haja um valor repetido, gerar um valor novo (que foi mais ou menos o que o Romário tentou fazer.
O problema que ocorre é: quem me garante que, quando eu gero um número novo, este não vai ser igual à outro número já existente?
Considerem o caso abaixo:
Tenho um array com 10 posições e quero preenchê-lo com valores que vão de 1 à 10. Eu caminho no vetor gerando um número aleatório para cada posição e, a cada posição, verifico se os valores gerados anteriormente são iguais ao que acabei de gerar. Isso parece bem simples. Mas imaginem o seguinte:
Atualmente estou na posição 8 e, graças à meu algoritmo, nenhum dos números se repetiu até o momento. Porém, quando eu gero o número da 8a posição, o mesmo coincide com o número da 6a posição. Com o algoritmo proposto pelo Romário, eu simplesmente geraria um número novo e verificaria as posições anteriores à 6a para ver se algum outro elemento repetiu-se. O que o Romário não considerou foi: o que acontece se, agora, o número novo coincidir com a 7a posição (que, na minha verificação, "ficou para trás")?
Como vocês podem ver, é um processo muito mais complexo do que parece ser.
Uma solução para o problema seria, ao invés de gerar um número aleatório entre 1 e 60, escolher um número em uma lista contendo apenas os números não previamente escolhidos. Uma forma de fazer isso seria com uma lista (FIFO) onde, para cada elemento adicionado ao array, o mesmo elemento seria removido da lista. Dessa forma, seria garantido que qualquer elemento "gerado" seria novo e não repetido no array.
Espero ter ajudado (apesar de crer que deixei mais dúvidas do que respostas).
Qualquer coisa, é só entrar em contato.