Imagine o seguinte cenário: você está jogando com um amigo, mas decide trapacear. Em vez de mover um navio depois que ele atira onde costumava estar, você decide não colocar nenhum navio. Você diz a ele que todos os seus tiros são errados, até que seja impossível colocar navios dessa maneira.
Você precisa escrever uma função, ou um programa completo, que de alguma forma leve três argumentos: o tamanho do campo, uma lista de quantidades de tamanhos de navios e uma lista de fotos.
Campo de batalha
Um dos parâmetros fornecidos é o tamanho da placa. O campo de batalha é um quadrado de células e o parâmetro fornecido é simplesmente um lado do quadrado.
Por exemplo, a seguir é uma placa de tamanho 5.
As coordenadas no campo são especificadas como uma sequência de dois componentes: uma letra seguida por um número. Você pode confiar nas letras em algum caso específico.
Letter especifica a coluna, number especifica a linha da célula (indexada 1). Por exemplo, na figura acima, a célula destacada é indicada por "D2"
.
Como existem apenas 26 letras, o campo não pode ser maior que 26x26.
Navios
Os navios são linhas retas de 1 ou mais blocos. A quantidade de navios é especificada em uma lista, onde o primeiro elemento é o número de navios com 1 célula, o segundo - navios com 2 células e assim por diante.
Por exemplo, a lista [4,1,2,0,1]
criaria o seguinte conjunto de remessas:
Quando colocados no campo de batalha, os navios não podem se cruzar ou até se tocar. Nem mesmo com cantos. No entanto, eles podem tocar as bordas do campo.
Abaixo, você pode ver um exemplo de colocação de navio válida:
Você pode supor que, para um determinado conjunto de navios, sempre exista um posicionamento em um tabuleiro vazio de determinado tamanho.
Saída
Se essas colocações de navios existirem, você deverá produzir uma delas.
O programa precisa produzir uma matriz separada por nova linha de caracteres ascii de qualquer um dos três tipos - um para indicar célula em branco, um - uma peça de navio e um - uma célula marcada como "perdida". Nenhum outro caractere deve ser produzido.
Por exemplo,
ZZ@Z
\@@Z
@\\Z
\Z\\
(Neste exemplo, eu defini @
como célula em branco, célula \
"perdida" e Z
peça de expedição)
Se esse posicionamento não existir, o programa / função deve retornar sem gerar nada.
Entrada
Se você decidir criar um programa completo, cabe a você especificar como as listas são inseridas, algumas podem ser via argumentos, outras via stdin.
Isso é código-golfe , a menor quantidade de caracteres ganha.
Um exemplo de solução otimizada sem golfe pode ser encontrado aqui
Compile com -std=c99
, o primeiro argumento é o tamanho do tabuleiro, os outros argumentos são os tamanhos dos navios. Uma lista de tiros separada por nova linha é fornecida no stdin. Exemplo:
./a 4 1 1 1 <<< $'A2\nA4\nB3\nC3\nC4\D4'
fonte
26x26
? Eu esbocei uma solução baseada em regexps e recursão, e ela fica extremamente lenta = inutilizável para campos acima de6x6
. Ou faço algo muito estúpido, ou falta de respostas significa que outros também não têm sucesso.10x10
com um4,3,2,1
shipsetRespostas:
GolfScript, 236 caracteres
A entrada é dada no STDIN. A primeira linha contém o tamanho e o número de navios, cada uma das coordenadas da linha a seguir de um único disparo.
Exemplo:
Eu pensei que também esse desafio deveria ter pelo menos uma resposta do GolfScript. No final, tornou-se muito pouco digno de nota devido ao algoritmo usado, que favorece o desempenho em detrimento da falta.
Código anotado:
fonte
SWI-Prolog,
536441 1 bytes1 final de linha UNIX, nova linha final não contada
A versão com todas as otimizações removidas ( 441 bytes):
Como o código foi alterado para minimizar o número de bytes, não aceitará mais uma lista de capturas que tenham duplicatas.
A versão com otimização básica, totalmente golfe ( 536 → 506 bytes)
Eu implico algumas verificações básicas ( contar o número de blocos de navios ) para tornar o código mais rápido em casos claramente impossíveis. O código também é imune a duplicar na lista de fotos até agora.
Abaixo está a versão (um tanto) legível, com comentários detalhados:
Formato da consulta:
Consulta de amostra (usando a amostra na pergunta):
fonte
Matlab - 536 caracteres
Atualizado: Formatação de saída muito menor, removidos alguns espaços em branco do loop.
Atualizado: versão golfed adicionada
Atualizado: versão comentada adicionada, versão reduzida para golfe em ~ 100 caracteres
Aqui está a versão do golfe.
Aqui estão algumas amostras.
A grande linha com 'kron' (perto da parte inferior do código não-golfe) é minha parte favorita disso. Ele grava um '1' em todos os locais no mapa vizinhos de uma determinada posição. Você pode ver como isso funciona? Ele usa o produto tensor kronecker, multiplicação de matrizes e indexa o mapa como uma matriz linear ...
fonte
Python, 464 caracteres
Entrada (stdin):
Saída:
Funciona usando números inteiros contendo bitmaps de vários recursos:
fonte
[::-1]
que faz com que tente o navio mais longo primeiro. Também regressa assim que encontra um navio que não pode colocar.Python, 562 caracteres, -8 com saída feia, +4? para invocação do bash
Nota: os níveis de recuo são espaço, tabulação, tabulação + espaço, tabulação + tabulação e tabulação + tabulação + espaço. Isso evita que alguns caracteres usem apenas espaços.
Uso e exemplo :
Recebe entrada dos argumentos da linha de comando. Emite um espaço em branco como espaço, um tiro como um
.
e a@
como parte de uma nave:Quando insolúvel, não imprime nada:
o
2>X
objetivo é suprimir uma mensagem de erro, pois o programa sai lançando uma exceção. Sinta-se livre para adicionar uma penalidade de +4 se considerado justo. Caso contrário, eu teria que fazer umtry: ... except:0
para suprimi-lo, o que levaria mais caracteres de qualquer maneira.Também posso imprimir a saída como números (
0
,1
e2
) para cortar 8 caracteres, mas valorizo a estética.Explicação :
Eu represento o quadro como uma lista de listas de números inteiros com tamanho 2 maior que a entrada, para evitar a verificação de limites.
0
representa um espaço vazio,1
um tiro e2
uma nave. Percorro a lista de tirosQ
e marquei todos os tiros. Eu converto a lista de navios em uma lista explícitaX
de navios, por exemplo,[4, 0, 2, 0, 1]
torna-se[5, 3, 3, 1, 1, 1, 1]
. Depois, é um algoritmo simples de retorno: em ordem decrescente de tamanho, tente colocar um navio e, em seguida, tente colocar o restante dos navios. Se não funcionar, tente o próximo slot. Assim que obtém êxito, a lista de envioX
é nula e o acessoX[0]
gera uma exceção que sai do programa. O resto é apenas golfe pesado (inicialmente tinha 1615 caracteres).fonte
Perl,
455 447 437 436 422418Recuado:
Eu espero que ele possa ser jogado ainda mais (por exemplo, com
eval<>
entrada pré-formatada, como eu vejo que está OK (?)), E também algumas outras coisas (50$
sigilos? Não, eles permanecerão).A velocidade, como eu disse anteriormente, pode ser um problema (de instantâneo (veja o exemplo abaixo) a muito muito longo), dependendo de onde a solução está na árvore de recursão, mas seja a questão da obsolescência do hardware usado. Vou fazer a versão otimizada mais tarde, com a recursão perdida e outros 2-3 truques óbvios.
É executado assim, 3 linhas sendo alimentadas através do STDIN:
~
é o oceano (solução artística, não é),o
's ex
s são navios e tiros. As primeiras 5 linhas obtêm a entrada e preparam nosso 'campo de batalha'.$N
é tamanho,@S
é um conjunto de navios desenrolado (por exemplo,1 1 1 1 2 3 3 5
como acima) e bifurca-se para a próxima iteração. E assim por diante.$f
é uma string que representa o campo de batalha (linhas com novas linhas concatenadas). A seguir, é apresentada uma sub-rotina recursiva, que espera o estado atual do campo de batalha e a lista dos navios restantes. Ele verifica da esquerda para a direita, de cima para baixo e tenta colocar cada navio em cada posição, horizontal e verticalmente (veja? Maduro para otimizar, mas isso será mais tarde). O navio horizontal é uma substituição óbvia do regexp, vertical um pouco mais complicado - manipulação de string bit a bit para substituir em 'column'. Em caso de sucesso (H, V ou ambos), novas posições inacessíveis são marcadas com!
Edit: OK, aqui está a versão de 594 bytes (quando não recuada) que realmente tenta ser útil (ou seja, rápida) - otimizada da melhor maneira possível, enquanto ainda implementa as mesmas técnicas - recursão (embora feita 'manualmente') e regexps. Ele mantém uma 'pilha' -
@A
- matriz de estados que vale a pena investigar. Um 'estado' é composto por 4 variáveis: sequência atual do campo de batalha, índice de onde começar a tentar colocar navios, referência ao conjunto de navios restantes e índice do próximo navio a tentar. Inicialmente, existe um único 'estado' - o início da cadeia vazia, todos os navios. Na partida (H ou V, veja acima), o estado atual é pressionado para investigar mais tarde, o estado atualizado (com um navio colocado e as posições inacessíveis marcadas) é pressionado e o bloco é reiniciado. Quando o final do campo de batalha é atingido sem êxito, o próximo estado disponível@A
é investigado (se houver).Outras otimizações são: não reiniciar desde o início da cadeia, tentar colocar navios grandes primeiro, não verificar navios do mesmo tamanho se o anterior falhou na mesma posição, + talvez outra coisa (como nenhuma
$&
variável etc.)..
OTOH, ainda leva uma eternidade para um caso impossível
6 5 4 3 2 1
no exemplo acima. Talvez a versão prática deva sair imediatamente se a tonelagem total do navio exceder a capacidade do campo de batalha.fonte
Solução c #
fonte
size=1 ships={1} moves={"A1"}
,.Java, 1178
Sim, por muito tempo.
Ungolfed:
Entrada de amostra
Saída de amostra
Com
O
chute perdido#
peça do navio_
atirar aqui em seguida ;-)Veja em ideone.com
O tratamento de entrada espera os espaços em torno dos números /
;
e não funcionará de outra maneira.Estou colocando grandes navios primeiro, pois eles têm menos lugares para ir. Se você deseja mudar para o menor primeiro, você pode substituir
pop()
porremove(0)
epush(s)
atéadd(0,s)
mesmo substituir apenas um dos dois ainda deve resultar em um programa válido.Se você permitir que navios se toquem, a
g(int,int)
função pode ser bastante simplificada ou removida.fonte