Toda luz Toda luz Toda luz!


13

Esse desafio é completamente inspirado no All Light , desenvolvido pela Soulgit Games.

Desafio

Você é eletricista e é seu trabalho conectar todas as luzes à bateria.

  • As luzes e a bateria estão dispostas em uma grade.
  • Você pode conectar uma luz ou bateria à luz ou bateria mais próxima ao norte, sul, leste e oeste.
  • A bateria pode ter qualquer número de conexões.
  • Cada luz especifica quantas conexões são necessárias. Você deve fazer exatamente tantas conexões com essa luz.
  • Você pode criar conexões únicas ou duplas entre duas luzes (ou luz e bateria).
  • Os fios não podem se cruzar.
  • Deve haver um caminho de cada luz para a bateria.
  • É garantida a existência de pelo menos uma solução válida.

Dada a posição da bateria e cada luz, e o número de conexões que cada luz requer, produza as conexões entre elas que admitem essas propriedades.

Condição da vitória

Isso é , então o código mais curto em cada idioma vence.

Casos de teste

A E / S é flexível, como de costume.

Para entrada, usarei uma matriz 2d do tamanho da grade que armazena números inteiros positivos para luzes, zeros para espaços em branco e -1 para a bateria. Outra boa opção pode ser uma lista de luzes, em que uma luz é uma tupla que contém a posição da luz e o número de conexões necessárias.

Para saída, usarei uma lista de conexões, onde uma conexão é uma tupla contendo a posição inicial e a posição final. Se uma conexão dobrar, terei 2 deles na lista (outra opção é incluir esse parâmetro na tupla). Outra boa opção pode ser algum tipo de layout de grade.

Se você estiver usando um sistema de coordenadas, poderá especificar o índice inicial e de onde é o índice. Meus exemplos serão indexados em 0 e usarão (0, 0) como o canto superior esquerdo (linha, coluna). (Estou usando {} simplesmente para introduzir outro tipo de delimitador, para facilitar a leitura, não porque sejam conjuntos.)

Aqui está uma visão gráfica dos casos de teste: Testes 1-12

Teste 1:

[-1 | 0 | 1 ] => [{(0, 0), (0, 2)}]

Teste 2:

[-1 | 0 | 2 ] => [{(0, 0), (0, 2)}, {(0, 0), (0, 2)}]

Teste 3:

[-1 ] [ 0 ] => [{(0, 0), (2, 0)), ((0, 0), (2, 0)}] [ 2 ]

Teste 4:

[ 1 | 0 |-1 | 0 | 2 ] => [{(0, 0), (0, 2)}, {(0, 2), (0, 4)}, {(0, 2), (0, 4)}]

Teste 5:

[ 2 ] [ 0 ] [-1 ] => [{(0, 0), (2, 0)}, {(0, 0), (2, 0)}, {(2, 0), (4, 0)}] [ 0 ] [ 1 ]

Teste 6:

[ 1 | 0 | 0 ] [ 0 | 0 | 0 ] => [{(0, 0), (2, 0)}, {(2, 0), (2, 2)}] [ 2 | 0 |-1 ]

Teste 7:

[ 4 | 0 | 0 |-1 ] [ 0 | 0 | 0 | 0 ] => [{(0, 0), (0, 3)}, {(0, 0), (0, 3)}, [ 2 | 0 | 0 | 0 ] {(0, 0), (3, 0)}, {(0, 0), (3, 0)}]

Teste 8:

[ 2 | 0 |-1 | 0 | 2 ] [{(0, 0), (0, 2)}, {(0, 0), (0, 2)}, [ 0 | 0 | 0 | 0 | 0 ] => {(0, 2), (0, 4)}, {(0, 2), (0, 4)}, [ 0 | 0 | 1 | 0 | 0 ] {(0, 2), (2, 2)}]

Teste 9:

[ 0 | 0 | 2 | 0 | 0 ] [ 0 | 0 | 0 | 0 | 0 ] [ 1 | 0 |-1 | 0 | 1 ] => [{(0, 2), (2, 2)}, {(0, 2), (2, 2)}, {(2, 0), (2, 2)}, [ 0 | 0 | 0 | 0 | 0 ] {(4, 2), (2, 2)}, {(2, 4), (2, 2)}, {(2, 4), (2, 2)}] [ 0 | 0 | 2 | 0 | 0 ]

Teste 10:

[-1 | 2 | 3 | 2 ] => [{(0, 0), (0, 3)}, {(0, 0), (0, 3)}, {(0, 0), (0, 3)}, {(0, 0), (0, 3)}]

Teste 11:

[-1 | 0 | 0 | 0 ] [ 3 | 0 | 0 | 0 ] [ 3 | 0 | 0 | 3 ] => [{(0, 0), (1, 0)}, {(1, 0), (2, 0)}, {(1, 0), (2, 0)}, [ 0 | 0 | 0 | 0 ] {(2, 0), (2, 3)}, {(2, 3), (4, 3)}, {(2, 3), (4, 3)}] [ 0 | 0 | 0 | 2 ]

Teste 12:

[ 2 | 0 | 0 ] [{(0, 0), (1, 0)}, {(0, 0), (1, 0)}, {(1, 0), (1, 1)}, [ 3 |-1 | 0 ] => {(1, 1), (2, 1)}, {(1, 1), (2, 1)}, {(2, 0), (2, 1)}, [ 2 | 5 | 1 ] {(2, 0), (2, 1)}, {(2, 1), (2, 2)}]



Sugiro ter um caso de teste de tal forma que exista uma solução que atenda a todas as condições, exceto "Deve haver um caminho de cada luz para a bateria". Por exemplo [1 | -1] [1 1].
usar o seguinte comando

Um pouco me lembra o algoritmo Blossom.
usar o seguinte comando

2
@ user202729 I garantia de que a entrada tem uma solução que satisfaça todas as condições
musicman523

1
Isso parece semelhante a um quebra-cabeça Hashi. Eu acho que muitos dos mesmos passos para resolver um deles são os mesmos.
Οurous

Respostas:


2

JavaScript (Node.js) , 393 391 378 bytes

a=>(R=[],f=(a,[x,...y],z,Y)=>x?f(a.map(t=>[...t]),y,z,Y)||f(a,y,[...z,x],Y.map(p=>p.map(q=>q-Y[x[0]][x[1]]?q:Y[x[2]][x[3]])),--a[x[0]][x[1]],--a[x[2]][x[3]]):/[1-9]/.test(a)|Y.some(t=>t.some(u=>u-Y[I][J]&&u))?0:z)(a=a.map(A=(b,i)=>b.map((x,j)=>x&&(A[i]+1&&R.push([i,A[i],i,j]),f[j]+1&&R.push([f[j],j,i,j]),A[I=i]=j,f[J=j]=i,x/=x>0))),[...R,...R],C=[],a.map(p=>p.map(q=>q&&++C)))

Experimente online!

a=>(
    a=a.map(
        A=(b,i)=>
            b.map(
                (x,j)=>
                    x&&(                                  // A[i]+1 <==> A[i] is NOT NaN
                        A[i]+1&&R.push([i,A[i],i,j]),     // Use A and f to store last
                        f[j]+1&&R.push([f[j],j,i,j]),     // existance of row and column
                        A[I=i]=j,f[J=j]=i,x/=x>0          // -1 => -Inf, +n => n
                    )
            ),
            R=[],
            f=([x,...y],z,Y)=>
                x?
                    f(
                        y,[...z,x],
                        Y.map(p=>p.map(q=>q-Y[x[0]][x[1]]?q:Y[x[2]][x[3]])), // merge
                        --a[x[0]][x[1]],--a[x[2]][x[3]]
                    )||
                    f(y,z,Y,++a[x[0]][x[1]],++a[x[2]][x[3]])
                :
                    /[1-9]/.test(a)|
                    Y.some(t=>t.some(u=>u-Y[I][J]&&u)) // not totally merged
                    ?0:z
    ),f)([...R,...R],[],a.map(p=>p.map(q=>q&&++C),C=0)
)


Existe um atalho para / [1-9] / no JavaScript RegEx?
Zacharý

@ Zacharý Acho que não. Normalmente [0-9]é usado
l4m2

Parvo eu! Eu pensei que isso é o que você escreveu
Zachary

@ Zacharý What ??
L4m2
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.