Quadrados Flippin '

34

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- 9e 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- 9devem ser usados ​​como instruções para virar as linhas e as letras A- Idevem 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 8meio vira a segunda linha da parte inferior e um Fmeio 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 2e, em seguida, inverter a coluna Ipara 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/2014 A 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))
Gareth
fonte
8
Acabei de escrever uma solução curta que inverteu linhas / colunas aleatoriamente até que a classificação fosse concluída. Após 500 milhões de iterações, ele ainda não havia resolvido o primeiro quebra-cabeça que você deu (onde você só precisa virar a linha 1). A aleatoriedade não parece ser uma solução utilizável para esse problema!
Josh
3
@ Josh Não é de surpreender. Esse problema parece ser muito semelhante à solução do cubo de um rubik. Acho que algum tipo de busca pela primeira vez seria a melhor força bruta. Dito isto, o algoritmo aleatório teoricamente tem que terminar eventualmente e parece se encaixar nas regras especificadas.
Cruncher
4
Força bruta não é necessária. Considere o fato de que cada bloco de grade só pode terminar em uma das quatro posições: seu local correto, X invertido, Y invertido ou XY invertido. Pode ajudá-lo a tratar mentalmente a grade como tendo (0,0) o bloco mais central. Se você está resolvendo telha (-2, 4), os únicos locais o número de destino pode ser é (-2, 4), (2, 4), (2, -4), ou (-2, -4).
Llama
2
@ Cruncher: Usar lançamentos de linhas / colunas inteiras torna isso impossível. Por exemplo, tente pegar o canto superior esquerdo 1 ( A1) e mova-o para B1. Você pode obter um 1para a posição B1, mas será o bloco de B9, não o bloco de A1. 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.
Llama
7
Parabéns, Gareth. Este é um problema muito bem projetado. Além disso, bastante desafiador.
21420 DavidC

Respostas:

7

GolfScript, 300 279 268 caracteres

n%`{\5,{.9+}%{;.2/\2%},\;''{1${.9/7+7*+}%+:z;}:?~{{.9<77*{\zip\9-}>:Z~{1$!{-1%}*\(\}@%\Z;}/}:E~{:^;{:c;.`{[\E[.^=\8^-=]{.c=\8c-=}%[^c+^8c-+8^-c+16c-^-]{9%49+}%=}+[[]]:K[[8^- 17c-][^9c+]1$]{:s;{[[]s.+.2$+]{1$+}/}%.&}/\,K+0=z?E}5,/}5,/{{+9%)}+9,%''*}9,%={z:u;}*}+1024,/u

Observe 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:

1A2C4D9G9G9G9G1C1C1C1C9F9F9F9F1D1D1D1D2A2A2A2A8H8H8H8H2B2B2B2B2C2C8F8F2D2D2D2D3A3A7I7I3B3B7H7H7G7G7G7G3D3D7F7F6I6I6I6I4A4A4A4A6H6H6H6H6G6G4C4C4C4C6F6F4D4D

1AB39I9I1A1A9I9I1B1B9F9F8I8I8I8I2B2B8H8H8G8G8G8G2D2D2D2D3A3A3A3A7H7H7H7H3C3C3C3C3D3D7F7F6I6I4A4A6I6I4B4B4B4B6G6G4C4C4C4C6F6F6F6F4D4D

1A34D9I9I9I9I1A1A1A1A1B1B1B1B9G9G1C1C1C1C9F9F9F9F1D1D9F9F8I8I2A2A2A2A8H8H8H8H2C2C2C2C8F8F2D2D8F8F7I7I7I7I3A3A3B3B7G7G7G7G3C3C3C3C6I6I6I6I6H6H6H6H4B4B4B4B6G6G6G6G4C4C6G6G6F6F4D4D6F6F
Howard
fonte
Bem, isso vai ser um trabalho muito difícil de bater este ...
Gareth
Parece que eu estava errado ...
Gareth
@Gareth Eu sabia que este é um desafio que seria difícil com o golfscript contra, por exemplo, o mathematica.
Howard
1
@ Howard - que abordagem você usou? O que é a "versão try-and-check" que você mencionou?
precisa saber é o seguinte
24

Mathematica 582 575 503 464 282

Para lutar com roteiristas de golfe, tenho que usar artilharia pesada!

i = "986553229
264564891
759176443
643982153
567891234
526917874
685328912
891732537
117644378";

a=Array;h@M_:=Join@@a[9(M〚##〛/. 9->9⌈2Random[]⌉)+Abs[{##}-5]&,n={9,9}];
For[i_~t~j_:=i{#2,10-#2}+j#-9&~a~{9,4},!ListQ[e=GroupElementToWord[
PermutationGroup[Cycles/@Join[1~t~9,9~t~1]],
h[ToCharacterCode@StringSplit@i-48]~FindPermutation~h@a[Mod[8+##,9,1]&,n]]],];
e~IntegerString~36<>""

Saída:

g69g69g8g8g7g7gd96d96d8d8d7d7dh6h64a6a46d6d4g4g6b6b7h7h7c7c2a8a27b7bd8db8b7f7fg8g82c2c94a4a3a3aigfdc91

Aqui, PermutationGroup[...]é possível configurar os lançamentos possíveis e GroupElementToWord[...]resolver o problema (cerca de 0.2s). O principal problema é que é difícil identificar a correspondência entre a posição de 9na 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:

g69g69g8g8g7g7gh89h89h7h7h6h6hf6f6g6g64f4f4h4hg7g73g3g2a8a28d8db8b83d3dg8g82c2c9a3a643a3a2g9f9d9c9ga
h89h89h7h7h6h6h6h6h6f6f6g6g6d6d3a7a37g7g7h7h3c3c2a8a27b7b8d8d2f2f8b8b3f3f2b2ba2a764a8aih9g9c9gb1i

Reproduz completamente os exemplos:

1
i
2i

Solução anterior (464)

sem funções internas inteligentes e com tempo de execução de 4 ms:

M=ToCharacterCode@StringSplit@i-48;
S="";s=Signature;H=(S=S<>{#,#2+9}~IntegerString~36)&;
A=(m=M〚##〛)-9Mod[m+##,2]&[s@{2#3,5}#,2#2#3~Mod~2-#2]&~Array~{4,4,4};
u=s/@Join@@A;
H@@({k,l}=#&@@@#~Position~1&/@{v=u〚13;;〛;{h=#2u〚2〛,-#u〚5〛,-#u〚9〛}&@@v,v〚4〛=u〚4〛h;v});
A〚k〛=A〚k,;;,{2,1,3,4}〛;A〚;;,l〛=A〚;;,l,{3,2,1,4}〛;
MapIndexed[4#≠#4&&H@@@If[#2<3,#0[#3,#,#2,#4];k,#0[#,#3,#4,#2];10-k]&@@
If[s@#<0,#〚{1,3,2,4}〛,#]&@Ordering[k={#2,#2};#]&,A,{2}];
M〚5,1〛<5&&5~H~{};M〚1,5〛<5&&{}~H~5;S

Todas as novas linhas aqui não são necessárias.

Saída:

3b9i9i1a1a1a1a9i9i1a1a9h9h1b1b1b1b9h9h9g9g1c1c9g9g9f9f1d1d9f9f8h8h2b2b8f8f8f8f7i7i7h7h3b3b3b3b7h7h3b3b7h7h7g7g3c3c7g7g3c3c7f7f6i6i4a4a6h6h4b4b4b4b6g6g4c4c6g6g4c4c6f6f4d4d4d4d6f6f4d4d6f6f4d4d

Outras duas grades de teste:

13ab9i9i1a1a9i9i9h9h1b1b1b1b9h9h9f9f8i8i8i8i8h8h2b2b2b2b8h8h8h8h8g8g8g8g8f8f2d2d2d2d8f8f2d2d7i7i3a3a3a3a7i7i7h7h3b3b7h7h3b3b7g7g3c3c3c3c7g7g3c3c7f7f3d3d3d3d7f7f7f7f6i6i4a4a6i6i6h6h4b4b4b4b6h6h4b4b6g6g4c4c4c4c6f6f4d4d4d4d6f6f4d4d6f6f
2bc9i9i1a1a9i9i9g9g1c1c9g9g1c1c9f9f1d1d1d1d8i8i8i8i8h8h2b2b2b2b8f8f2d2d7i7i7h7h3b3b3b3b7h7h3b3b7g7g3c3c7f7f3d3d3d3d7f7f3d3d6i6i4a4a4a4a6h6h4b4b6g6g6g6g6f6f4d4d

Visualização:

anim = Reap[Fold[Function[{m, i}, 
 If[i > 9, (Sow@Grid[#, Background -> {i - 9 -> Pink, None}] & /@ {m, #}; #) &@
   Transpose@MapAt[Reverse, Transpose@m, i - 9], (Sow@Grid[#, 
         Background -> {None, i -> Pink}] & /@ {m, #}; #) &@
   MapAt[Reverse, m, i]]], M, IntegerDigits[FromDigits[S, 36], 36]]];

ListAnimate[Join[{#, #} &@Grid@M, anim[[2, 1]], {#, #} &@Grid@anim[[1]]], 5]

insira a descrição da imagem aqui

A sequência de entrada ipode ser gerada aleatoriamente por

M = Array[Mod[8 + ##, 9, 1] &, {9, 9}];
(M[[#]] = Reverse@M[[#]]; M[[All, #2]] = Reverse@M[[All, #2]];) & @@@
   RandomInteger[{1, 9}, {10000, 2}];
i = ToString /@ # <> "\n" & /@ M <> ""

Breve discussão

  • Os flips podem trocar apenas esses elementos ("quádruplo"):

    insira a descrição da imagem aqui

  • É 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!

M=ToCharacterCode@StringSplit@i-48;

Converta a string ina matriz M.

S="";s=Signature;H=(S=S<>{#,#2+9}~IntegerString~36)&;

Anexaremos caracteres a S. Agora é a string vazia. H[i,j]adicionará o caractere i( 1,2,3,...,9) e o caractere j( a,b,c,...,ina base 36).

A=(m=M〚##〛)-9Mod[m+##,2]&[s@{2#3,5}#,2#2#3~Mod~2-#2]&~Array~{4,4,4};

Eu converto elementos como

insira a descrição da imagem aqui

para obter a matriz de destino da seguinte forma

insira a descrição da imagem aqui

Existem duas etapas principais no meu algoritmo

  1. Encontre flips para obter as assinaturas como na matriz de destino (por exemplo, a assinatura de {-7,-1,1,7}is 1e a assinatura de {-6,2,-2,6}is -1):

    u=s/@Join@@A;
    H@@({k,l}=#&@@@#~Position~1&/@{v=u〚13;;〛;{h=#2u〚2〛,-#u〚5〛,-#u〚9〛}&@@v,v〚4〛=u〚4〛h;v});
    A〚k〛=A〚k,;;,{2,1,3,4}〛;A〚;;,l〛=A〚;;,l,{3,2,1,4}〛;
    
  2. Gire cada "quádruplo" para obter a ordem correta:

    MapIndexed[4#≠#4&&H@@@If[#2<3,#0[#3,#,#2,#4];k,#0[#,#3,#4,#2];10-k]&@@
    If[s@#<0,#〚{1,3,2,4}〛,#]&@Ordering[k={#2,#2};#]&,A,{2}];
    

    É a parte mais trivial do algoritmo. Por exemplo, a transformação 1b1bserá convertida {-7,-1,1,7}em {-1,1,-7,7}. A transformação 9h9hserá convertida {-7,-1,1,7}em {-7,7,-1,1}. Então nós temos dois mapas

    {1,2,3,4} -> {2,3,1,4}
    {1,2,3,4} -> {1,4,2,3}
    

    e queremos converter uma ordem arbitrária {x,y,z,w}em {1,2,3,4}. O método simples é (exceto uma pesquisa aleatória)

    repeat   
    {x, y, z, w} -> If[z < 3, {y, z, x, w}, {x, w, y, z}]
    until {1,2,3,4}
    

    Não posso provar, mas funciona!

O último passo é

M〚5,1〛<5&&5~H~{};M〚1,5〛<5&&{}~H~5;S

Ele executa movimentos triviais da linha central e da coluna central e retorna o resultado.

ybeltukov
fonte
@Gareth Posso usar caracteres pequenos na saída? Isso me salva vários caracteres.
precisa saber é o seguinte
Sim, aceitarei caracteres minúsculos na saída (vou mudar a pergunta para observar isso). Eu não tenho o Mathematica, então algum outro usuário do Mathematica pode confirmar que o código realmente gera a saída? Eu validei as três soluções de teste e todas estão corretas, então +1. Bom trabalho!
Gareth
Apenas curioso - qual é o desempenho de sua abordagem? Você testou as entradas geradas por milhares de flips?
precisa saber é o seguinte
@SergeyS Sim, leva cerca de 50 ms :)
ybeltukov
@Gareth Reescrevi meu programa, você pode verificar os resultados? Meus testes mostraram que tudo está correto.
precisa saber é o seguinte
7

J 487 438

q=:3 :'(>:9|+/~i.9)=/&((,{;/(,.8&-)y){])g'
l=:2 :0
:
o=:o,(m+x){a.
x&(|.@{`[`]})&.v y
)
r=:49 l]
c=:97 l|:
w=:2 :'g=:4 v^:(4=(<m){g)g'
p=:_1=C.!.2@,@:I.@q
t=:2 :'for_i.>:i.3 do.g=:i v^:(p m*i)g end.'
z=:2 :0
'i j I J'=.y,8-y
g=:".'(',(,' ',.,(I.m{q y){,;._1 n),'])^:2 g'
)
d=:3 :0
g=:9 9$".,_ list,' ',.y
o=:''
0 4 w c
4 0 w r
0 1 t c
g=:0 c^:(-.(p 1 0)=p 1 2)g
1 0 t r
for_k.>,{;~i.4 do.0 z';;jcir;irjc;Irjc'k
3 z';;IrJc;JcIr;'k end.o
)

d é um verbo que pega uma string de grade no formato especificado e retorna uma string de solução no formato especificado.

Exemplo de uso:

   d '987654321',LF,'234567891',LF,'345678912',LF,'456789123',LF,'567891234',LF,'678912345',LF,'789123456',LF,'891234567',LF,'912345678'
bcda2341a1a1b1b1c1c1d1da2a2b2b2c2c2d2d2a3a3b3b3c3c3d3d3a4a4b4b4c4c4d4d4

Agora aceita qualquer tipo de nova linha.

Soluções para as grades de teste:

b3a1a11b1bc9c99g9gd9d99f9fb8b8f8f87i7i7h7hc3c3g7g77f7fa6a64b4bh6h6c4c4g6g6d6d6f6f6
cd24a9a91c1c1d1d9f9fa2a2i8i88h8hc2c2g8g82d2d3b3bh7h7d3d37f7fa6a64b4bg6g64d4d6f6f
bc2a9a99i9ic1c1g9g91d1df9f9i8i8b2b2h8h82c2cd8d87i7ib3b3c7c7d3d34a4ai6i6b6b6g6g6d6d6

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 dpara:

if.-.+./89 90=#y do.0 return.end.if.-.*./(/:~y)=/:~(#y)$'123456789',LF do.0 return.end.g=:9 9$".,_ list,' ',.y

e a última linha para isso:

3 z';;IrJc;JcIr;'k end.if.*./,g=>:9|+/~i.9 do.o return.end.0

Eu escolhi retornar 0esses 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).

AlliedEnvy
fonte
Parabéns, você acabou de assumir a liderança. :-)
Gareth
Parece que sua entrada não é uma string, conforme exigido pelas regras, ou eu sinto falta de alguma coisa?
precisa saber é o seguinte
@ EmeryS: Você pode estar confuso. Até onde eu sei, J não tem como colocar escapes (como nova linha) em literais de string. A construção 'a', LF, 'b' em J é semelhante a "a" + "\ n" + "b" nos idiomas em que + trabalha para acrescentar seqüências de caracteres.
AlliedEnvy
Ok, faz sentido, obrigado.
SergeyS
Eu estava lendo a seção sobre arquivos do livro da APL de 1962 e acho que @AlliedEnvy está correto. É assim que os dados aparecerão no programa se forem lidos de um arquivo no formato da pergunta. Os LFs representam partições do arquivo seqüencial.
Luser droog
5

C # 540 399

Bem, 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!

string S(string _){for(i=0,e=1>0;e;){
for(h=v=j=0;j<89;)m[j/10,j%10+9]=_[j++]-49;a="";
for(j=i++;j>0;v++,j/=2)if(j%2>0)F(v);
for(;h<9&(h<4|!e);h+=j/36,j%=36)if((e=m[h,g=j++%9+9]!=(t=(h+g)%9))|m[v=8-h,g]==t){F(v);F(g);F(v);F(g);}
}return a;}void F(int z){for(f=z<9;++l<9;)m[0,l]=m[f?z:l,f?9+l:z];for(;l-->0;)m[f?z:l,f?9+l:z]=m[0,8-l];a+=(char)(z+=f?49:56);}
dynamic h,v,i,j,e,t,l=-1,g,a,m=new int[9,19],f;

Grelhas de teste:

3B9A9A9B9B9C9C9D9D9F9F9G9G9H9H9I9I9B9B9C9C9D9D9F9F9G9G9H9H9C9C9D9D9C9C9D9D8B8B8F8F8H8H8B8B8F8F8B8B8H8H7B7B7C7C7F7F7H7H7I7I7H7H6A6A6B6B6C6C6D6D6F6F6H6H6A6A6B6B6D6D6F6F6D6D6D6D6F6F5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I

13AB9A9A9B9B9F9F9H9H9A9A9B9B9H9H9I9I8B8B8D8D8F8F8G8G8H8H8I8I8B8B8G8G8H8H8I8I8H8H7A7A7B7B7C7C7D7D7F7F7G7G7I7I7A7A7D7D7F7F7I7I7F7F6A6A6B6B6C6C6D6D6F6F6G6G6H6H6I6I6A6A6C6C6F6F6I6I6A6A6A6A5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I

2BC9A9A9C9C9D9D9F9F9A9A9D9D9I9I8B8B8D8D8H8H8I8I8B8B8D8D8I8I7B7B7C7C7D7D7F7F7G7G7H7H7I7I7C7C7C7C7G7G6A6A6B6B6D6D6F6F6G6G6I6I6A6A6B6B6D6D6G6G6D6D6F6F5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I5A5A5B5B5C5C5D5D5E5E5F5F5G5G5H5H5I5I

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

string S(string[]_){for(i=0;i<1<<18;){
for(j=0;j<81;)m[j/9+49,j%9+65]=_[j/9][j++%9]-49;a="";char g,h='1',v='9',b,x=h,y;
for(j=i;j>0;x=x==v?'A':++x,j/=2)if(j%2>0)F(x);j=i+1;
for(i+=1<<19;h<58;h++,v--)for(g='A',b='I';g<74;g++,b--){
t=(h+g-6)%9;e=m[h,g];q=m[v,g];i=h>52&t!=e?j:i;
if(e!=t|q==t){x=q==t?v:g;y=q==t?g:v;
if(m[h,b]==t){x=b;y=h;}
F(x);F(y);F(x);F(y);}}}return a;}
void F(char z){var f=z<65;for(l=0;l<4;l++){n=m[d=f?z:49+l,s=f?65+l:z];m[d,s]=m[o=f?z:57-l,u=f?73-l:z];m[o,u]=n;}a+=z;}
int i,j,q,e,t,l,s,d,n,u,o;int[,]m=new int[99,99];string a;

Resposta por exemplo 1:

15A5A5B5B5C5C5D5DE5E55F5F5G5G5H5H5I5I

Resposta por exemplo 2:

19AI1I1H1H1G1G1F1F19F9F9G9G9H9H9I9I8A8AI8I87A7AI7I76A6AI6I65A5A5B5B5C5C5D
5DE5E55F5F5G5G5H5H5I5I

Resposta por exemplo 3:

129AI1I1H1H1G1G1F1F19F9F9G9G9H9H9I9I8A8AI8I87A7AI7I76A6AI6I65A5A5B5B5C5C5
D5DE5E55F5F5G5G5H5H5I5I

Respostas para quadrados de teste:

346B9A9AH1H1C9C9D9D99F9F9G9GH9H99I9IB8B8F8F87B7B7C7C7F7FH7H77I7I6A6A6B6BC6C66D6DG6G6H6H66I6I5A5A5B5B5C5C5D5DE5E55F5F5G5G5H5H5I5I

1346ABA9A9H1H19F9FH9H99I9IH2H28D8D8F8FG8G8I8I8I3I37B7B7C7CF3F37G7GI7I7H4H4D6D66F6F5A5A5B5B5C5C5D5DE5E55F5F5G5G5H5H5I5I

2BCA9A99C9CF1F19F9F9I9IH2H2D8D88H8HI8I87B7BC7C77D7D7F7F7H7H7I7II4I4B6B6D6D6G6G66I6I5A5A5B5B5C5C5D5DE5E55F5F5G5G5H5H5I5I
SergeyS
fonte
Estou apenas baixando o Mono para o meu Mac agora, para que eu possa testar o programa, mas já tenho um validador que executa uma determinada solução em uma determinada grade e me diz se a solução é uma solução válida para essa grade - e é me dizendo que as três soluções de exemplo que você me deu não são válidas. Só estou investigando o porquê agora.
Gareth
Aha! Eu descobri o que aconteceu aqui! Suas respostas parecem ser respostas para os 3 exemplos e não para as três grades de teste (que estão mais abaixo na pergunta). Na verdade, são soluções corretas para essas grades, embora sejam um pouco mais longas que 1, Ae 2Iquais 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.
Gareth
@Gareth - oops, eu perdi respostas para quadrados de teste, obrigado por apontar isso. Eu os adicionei agora à minha resposta.
precisa saber é o seguinte
Excelente, obrigado por isso. Todos eles validaram bem. O Xamarin não funcionaria no meu Mac por algum motivo, então terei que testar o programa no trabalho em algumas horas.
Gareth
@Gareth - Na verdade, não há nada específico para C # nesse código, provavelmente é possível convertê-lo para Java ou mesmo C ++ sem muita dor e ... tirar alguns caracteres dele :) Também sinta-se à vontade para convertê-lo em GolfScript ou algo mais conciso - isso pode parecer duas ou mais curto;)
SergeyS