Geralmente, uma tarefa requer matrizes reais. Tomemos, por exemplo, a tarefa de implementar o Befunge ou> <>. Tentei usar o Array
módulo para isso, mas é realmente complicado, pois parece que estou codificando muito detalhadamente. Alguém pode me ajudar a resolver essas tarefas de código-golfe menos detalhadas e mais funcionais?
11
Respostas:
Antes de tudo, recomendo examinar o Data.Vector , uma alternativa mais agradável ao Data.Array em alguns casos.
Array
eVector
são ideais para alguns casos de memorização, conforme demonstrado na minha resposta para "Encontrar caminhos máximos" . No entanto, alguns problemas simplesmente não são fáceis de expressar em um estilo funcional. Por exemplo, o Problema 28 no Projeto Euler pede somar os números nas diagonais de uma espiral. Claro, deve ser bem fácil encontrar uma fórmula para esses números, mas construir a espiral é mais desafiador.Data.Array.ST fornece um tipo de matriz mutável. No entanto, a situação do tipo é uma bagunça: ela usa uma classe MArray para sobrecarregar cada um de seus métodos, exceto o runSTArray . Portanto, a menos que você planeje retornar uma matriz imutável a partir de uma ação de matriz mutável, será necessário adicionar uma ou mais assinaturas de tipo:
No entanto, minha solução para o Euler 28 resultou muito bem e não exigia a assinatura desse tipo porque eu o usava
runSTArray
.Usando Data.Map como uma "matriz mutável"
Se você deseja implementar um algoritmo de matriz mutável, outra opção é usar o Data.Map . Quando você usa uma matriz, você deseja ter uma função como esta, que altera um único elemento de uma matriz:
Infelizmente, isso exigiria a cópia de toda a matriz, a menos que a implementação usasse uma estratégia de copiar na gravação para evitá-la quando possível.
A boa notícia é que,
Data.Map
tem uma função como esta, insira :Como
Map
é implementado internamente como uma árvore binária balanceada,insert
ocupa apenas O (log n) tempo e espaço e preserva a cópia original. Portanto,Map
não apenas fornece uma "matriz mutável" um tanto eficiente que é compatível com o modelo de programação funcional, mas também permite "voltar no tempo", se assim o desejar.Aqui está uma solução para o Euler 28 usando o Data.Map:
Os padrões de estrondo impedem que um estouro de pilha causado pelos itens do acumulador (cursor, número e mapa) não seja usado até o final. Para a maioria dos golfistas de código, os casos de entrada não devem ser grandes o suficiente para precisar dessa provisão.
fonte
A resposta rápida é: Não use matrizes. A resposta não tão simplista é: tente repensar seu problema para que ele não precise de matrizes.
Freqüentemente, um problema com alguma reflexão pode ser resolvido sem nenhuma matriz semelhante à estrutura. Por exemplo, aqui está a minha resposta para Euler 28:
O que é expresso no código aqui é o padrão da sequência de números à medida que crescem em torno da espiral retangular. Não havia necessidade de representar a própria matriz de números.
A chave para pensar além das matrizes é pensar sobre o que o problema em questão realmente significa, não como você pode representá-lo como bytes na RAM. Isso só vem com a prática (talvez uma razão pela qual eu tanto codigo de golfe!)
Outro exemplo é como eu resolvi a busca de caminhos máximos code-golf. Lá, o método de passar as soluções parciais como uma onda através da matriz, linha por linha, é expresso diretamente pela operação de dobra. Lembre-se: Na maioria das CPUs, você não pode lidar com a matriz como um todo de uma só vez: o programa terá que operar com ela ao longo do tempo. Pode não ser necessário todo o array de uma só vez, a qualquer momento.
Obviamente, alguns problemas são declarados de forma a serem inerentemente baseados em array. Idiomas como> <>, Befunge ou Brainfuck têm matrizes no coração. No entanto, mesmo lá, as matrizes geralmente podem ser dispensadas. Por exemplo, veja minha solução para interpretar Brainfuck , o verdadeiro núcleo de sua semântica é um zíper . Para começar a pensar dessa maneira, concentre-se nos padrões de acesso e na estrutura mais próxima do significado do problema. Muitas vezes, isso não precisa ser forçado a uma matriz mutável.
Quando tudo mais falhar e você precisar usar uma matriz - as dicas do @ Joey são um bom começo.
fonte