Crie um programa ou função para desordenar um quadrado de dígitos, invertendo (invertendo o ponto central) apenas as linhas e colunas.
Entrada
A entrada será uma grade 9x9 de dígitos na forma de uma sequência de 9 linhas, como a seguir:
986553229
264564891
759176443
643982153
567891234
526917874
685328912
891732537
117644378
Esse formato de entrada não é negociável - todas as soluções "criativas" com o formato de entrada serão consideradas inválidas.
Saída
A saída deve ser uma lista de movimentos que, quando aplicados à entrada na ordem especificada, devem recriar a grade de destino.
Um exemplo de saída (não uma solução para o exemplo de entrada anterior):
28IF5D3EAB9G3
Esse formato de saída também não é negociável. Não deve haver novas linhas ou espaços na saída, apenas os caracteres 1
- 9
e A
- I
(caracteres minúsculos são aceitáveis no lugar de caracteres maiúsculos, se preferir).
A grade de destino (o estado que você precisa recriar) é a seguinte:
123456789
234567891
345678912
456789123
567891234
678912345
789123456
891234567
912345678
Os números 1
- 9
devem ser usados como instruções para virar as linhas e as letras A
- I
devem ser usados para as colunas. Isso é mostrado abaixo com a grade em seu estado restaurado.
ABCDEFGHI
|||||||||
vvvvvvvvv
1 -> 123456789
2 -> 234567891
3 -> 345678912
4 -> 456789123
5 -> 567891234
6 -> 678912345
7 -> 789123456
8 -> 891234567
9 -> 912345678
Então, um 8
meio vira a segunda linha da parte inferior e um F
meio vira a sexta coluna.
Caso nenhuma solução seja possível, o programa deve terminar sem gerar nada.
Exemplos
Entrada:
987654321
234567891
345678912
456789123
567891234
678912345
789123456
891234567
912345678
Saída:
1
Nesse caso, apenas a linha superior precisa ser invertida para retornar ao estado da meta.
Entrada:
123456788
234567897
345678916
456789125
567891234
678912343
789123452
891234561
912345679
Saída:
I
Nesse caso, apenas a coluna final (coluna I
) precisa ser invertida para recriar o estado da meta.
Entrada:
123456788
798765432
345678916
456789125
567891234
678912343
789123452
891234561
912345679
Saída:
2I
Nesse caso, precisamos inverter a linha 2
e, em seguida, inverter a coluna I
para retornar ao estado do objetivo.
Notas:
- Inclua um exemplo de uso em sua resposta.
- A saída fornecida não precisa ser a sequência mais curta que retornará o estado do objetivo - qualquer sequência que retorne o estado do objetivo funcionará enquanto funcionar (ou seja, desde que eu possa testá-lo)
- Vou me esforçar para testar cada resposta e aprovar todas as que funcionam e obviamente tiveram uma tentativa de jogar golfe.
- Esta é uma competição aberta - aceitarei a resposta mais curta na próxima semana, mas se surgir uma resposta válida mais nova que seja mais curta a qualquer momento no futuro, alterarei a resposta aceita para refletir isso .
A recompensa foi definida como 200 reputação para a resposta mais curta recebida até 23:59:59 (GMT) em 26/01/2014A recompensa foi concedida a Howard por sua solução GolfScript de 268 caracteres .
Teste
Forneça a saída do seu programa para as três grades de teste a seguir com sua resposta:
986553229
264564891
759176443
643982153
567891234
526917874
685328912
891732537
117644378
927354389
194762537
319673942
351982676
567891234
523719844
755128486
268534198
812546671
813654789
738762162
344871987
341989324
567891234
576217856
619623552
194435598
926543271
Eu criei um pequeno programa Python para gerar grades válidas para fins de teste:
import random
def output(array):
print '\n'.join([''.join(row) for row in array])
def fliprow(rownum, array):
return [row[::1-2*(rownum==idx)] for idx,row in enumerate(array)]
def flipcol(colnum, array):
return zip(*fliprow(colnum, zip(*array)))
def randomflip(array):
op=random.randint(0,1)
row=random.randint(0,9)
if(op==1):
return fliprow(row, array)
else:
return flipcol(row, array)
def jumble(array):
arraycopy=array
for i in range(10, 1000):
arraycopy=randomflip(arraycopy)
return arraycopy
startarray=[
['1','2','3','4','5','6','7','8','9'],
['2','3','4','5','6','7','8','9','1'],
['3','4','5','6','7','8','9','1','2'],
['4','5','6','7','8','9','1','2','3'],
['5','6','7','8','9','1','2','3','4'],
['6','7','8','9','1','2','3','4','5'],
['7','8','9','1','2','3','4','5','6'],
['8','9','1','2','3','4','5','6','7'],
['9','1','2','3','4','5','6','7','8']]
print output(jumble(startarray))
(-2, 4)
,(2, 4)
,(2, -4)
, ou(-2, -4)
.A1
) e mova-o paraB1
. Você pode obter um1
para a posiçãoB1
, mas será o bloco deB9
, não o bloco deA1
. Como só é permitido o lançamento de linhas / colunas inteiras, o canto superior esquerdo 1 estará sempre em um dos quatro cantos mais externos. Se eu tiver errado as regras, entre em contato.Respostas:
GolfScript,
300279268 caracteresObserve que esse código é extremamente lento (também devido à manipulação pesada de bloco de código) e pode demorar vários minutos. O código é muito un-golfscript-ish com muitas variáveis e loops explícitos.
Eu havia escrito uma solução mais analítica que funcionava por menos de um segundo. Eu quebrei completamente esse durante o golfe. Infelizmente, não consegui voltar atrás ou reparar o código nos últimos dois dias. Portanto, eu produzi esta versão try-and-check, que é mais curta de qualquer maneira.
As respostas para os quebra-cabeças dadas acima:
fonte
Mathematica
582575503464282Para lutar com roteiristas de golfe, tenho que usar artilharia pesada!
Saída:
Aqui,
PermutationGroup[...]
é possível configurar os lançamentos possíveis eGroupElementToWord[...]
resolver o problema (cerca de0.2
s). O principal problema é que é difícil identificar a correspondência entre a posição de9
na grade inicial e final. Para jogar golfe, eu faço isso aleatoriamente (leva alguns segundos). Existem alguns avisos, mas é possível ignorá-los.Outro para testar grades:
Reproduz completamente os exemplos:
Solução anterior (464)
sem funções internas inteligentes e com tempo de execução de 4 ms:
Todas as novas linhas aqui não são necessárias.
Saída:
Outras duas grades de teste:
Visualização:
A sequência de entrada
i
pode ser gerada aleatoriamente porBreve discussão
Os flips podem trocar apenas esses elementos ("quádruplo"):
É possível trocar esses elementos separadamente de outros elementos somente se o pedido inicial e o final tiverem a mesma assinatura.
Os movimentos desses quatro elementos formam o grupo alternado de grau 4 (= grupo de rotações do tetraédrico). Cada elemento deste grupo é uma composição de 2 elementos geradores. Portanto, se conhecermos a posição inicial e final, podemos decompor a transformação correspondente como uma combinação de um movimento simples.
Detalhes
Por espírito esportivo, posto detalhes antes do final da recompensa!
Converta a string
i
na matrizM
.Anexaremos caracteres a
S
. Agora é a string vazia.H[i,j]
adicionará o caracterei
(1,2,3,...,9
) e o caracterej
(a,b,c,...,i
na base 36).Eu converto elementos como
para obter a matriz de destino da seguinte forma
Existem duas etapas principais no meu algoritmo
Encontre flips para obter as assinaturas como na matriz de destino (por exemplo, a assinatura de
{-7,-1,1,7}
is1
e a assinatura de{-6,2,-2,6}
is-1
):Gire cada "quádruplo" para obter a ordem correta:
É a parte mais trivial do algoritmo. Por exemplo, a transformação
1b1b
será convertida{-7,-1,1,7}
em{-1,1,-7,7}
. A transformação9h9h
será convertida{-7,-1,1,7}
em{-7,7,-1,1}
. Então nós temos dois mapase queremos converter uma ordem arbitrária
{x,y,z,w}
em{1,2,3,4}
. O método simples é (exceto uma pesquisa aleatória)Não posso provar, mas funciona!
O último passo é
Ele executa movimentos triviais da linha central e da coluna central e retorna o resultado.
fonte
J
487438d
é um verbo que pega uma string de grade no formato especificado e retorna uma string de solução no formato especificado.Exemplo de uso:
Agora aceita qualquer tipo de nova linha.
Soluções para as grades de teste:
Eu sou bastante novo em J; isso provavelmente poderia ser jogado ainda mais.
A verificação de grades inválidas / insolúveis incorre em uma penalidade de 123 caracteres. Eu não acho que as outras respostas até o momento tenham essa verificação de erro.
Para fazer isso, altere a primeira linha
d
para:e a última linha para isso:
Eu escolhi retornar
0
esses erros, pois retornar uma string vazia seria indistinguível de resolver corretamente uma grade totalmente resolvida. Observe que isso assume novas linhas do UNIX (novamente).fonte
LF
s representam partições do arquivo seqüencial.C #
540399Bem, desempenho sacrificado (agora leva até 30 segundos), introduziu variáveis dinâmicas, lógica de solução ligeiramente alterada. E sim, agora espera entrada como uma sequência com quebras de linha (conforme exigido nas regras).
É claro que o C # não possui funções matemáticas predefinidas, por isso seria difícil lutar com os caras do Mathematica. No entanto, este foi um grande desafio, graças ao autor!
Grelhas de teste:
Solução antiga (540)
Funciona em menos de um segundo em qualquer entrada (testada em milhares de grades geradas aleatoriamente). O comprimento máximo da cadeia de saída é 165 (inicialmente qualquer grade foi resolvida em não mais que 82 movimentos, mas durante o golfe eu sacrifiquei isso).
Resposta por exemplo 1:
Resposta por exemplo 2:
Resposta por exemplo 3:
Respostas para quadrados de teste:
fonte
1
,A
e2I
quais são as soluções mais simples - mas isso realmente não importa, pois não estou julgando o tamanho da solução da grade :-) Se você pudesse editar e dê as respostas para as três grades de teste (vou ver se consigo colocar isso em execução no meu Mac agora) posso dar o seu +1.