Publicações arquivadas sob Tecnologia
Estou usando o Eclipse Galileo no trabalho para programar em Java e de repente, no modo de Debug, nenhum breakpoint é respeitado: todos passam direto.
Procurei um pouco na net e descobri que é um problema do JDK 1.6.0.14.
Usem outra versão -> A 1.6.0.16 corrige esse problema.
Fonte
13 de Agosto de 2009 às 14:52
Thiago
Ontem fiz um programa para resolver o 8 puzzle. Testei em casa com o puzzle presente no jogo Professor Layton e para minha tristeza o programa era lento demais. Deixei ligado por vários minutos e a resposta não apareceu. Logicamente precisava aumentar a performance e a maneira mais óbvia era trocar o algoritmo de busca, já que a busca em largura, apesar de dar a resposta correta, é muito lenta.
Dito isto, troquei para o algoritmo A*, que é o super bambambam dos algoritmos de busca. Para implementar este algoritmo, preciso de uma fila de prioridade e felizmente a biblioteca de Python já possui uma implementação no módulo heapq. Também é preciso associar um custo com cada configuração do tabuleiro e fiz da seguinte forma: o custo de um configuração é a soma da quantidade de movimentos até chegar nela mais a soma das distâncias Manhattan de cada quadrado até sua posição na configuração final. Usei uma matriz bacana para armazenar fácil essas distâncias, hehe!
Por fim, rodei o programa e dentro de poucos minutos ele deu uma resposta. Testei e a resposta está correta. Até que enfim resolvi esse puzzle terrível! O código está abaixo.
Yesterday I wrote a program to solve the 8 puzzle, but my implementation was too slow. I changed the search algorithm to A* and everyting worked just fine. I finally got through that pesky puzzle in the game.
"""
This is a solver for the 8 sliders puzzle.
A state is a snapshot of the game board. It is represented by a list of
9 items, eg. [0,1,2,3,4,5,6,7,8]. The positions in the list map to the
following positions on the board:
0 1 2
3 4 5
6 7 8
We assume the square labelled 0 is the empty square. It is possible
to have more of the same number on the board.
"""
# A Priority Queue implementation
import heapq
""" The allowed moves in the game. For example, 0:[1,3] means that
a square in position zero can be swapped with the square in position one
or the square in position three.
"""
SWAPS = {0:[1,3],
1:[0,2,4],
2:[1,5],
3:[0,4,6],
4:[1,3,5,7],
5:[2,4,8],
6:[3,7],
7:[4,6,8],
8:[5,7]}
def solve_eight_puzzle(begin, goal):
distance = calculate_distance(goal)
openlist = []
heapq.heappush(openlist, package_cost(begin, 0, distance))
closedlist = []
previous = {begin:None}
while len(openlist) > 0:
print len(openlist),
cost, state = heapq.heappop(openlist)
closedlist.append(state)
if state == goal:
s = goal
path = []
while previous[s] is not None:
path.append(s)
s = previous[s]
path.append(s)
path.reverse()
return path
nextstates = [s for s in possible_moves(state) if s not in closedlist]
for next in nextstates:
previous[next] = state
heapq.heappush(openlist, package_cost(next, cost + 1, distance))
return None
def package_cost(state, path_length, distance):
cost = path_length
for i in range(9):
cost += distance[state[i]][i]
return (cost, state)
def possible_moves(state):
izero = index_of_zero(state)
swaps = SWAPS[izero]
new_states = []
for swap in swaps:
new_state = list(state)
new_state[izero] = state[swap]
new_state[swap] = state[izero]
new_states.append(tuple(new_state))
return new_states
def instructions(state_list):
answer = []
previous = None
for state in state_list:
if previous is not None:
izero1 = index_of_zero(previous)
izero2 = index_of_zero(state)
if izero1 / 3 < izero2 / 3:
# zero went down
inst = "move a piece up"
elif izero1 / 3 == izero2 / 3:
if izero1 < izero2:
# zero went right
inst = "move a piece left"
else:
#zero went left
inst = "move a piece right"
elif izero1 / 3 > izero2 / 3:
# zero went up
inst = “move a piece down”
answer.append(inst)
previous = state
return answer
def index_of_zero(tup):
i = 0
while i < 9:
if tup[i] == 0:
return i
i += 1
print "Mega error: there is no ZERO in", tup
def calculate_distance(goal):
distance = {}
distance[goal[0]] = [0, 1, 2, 1, 2, 3, 2, 3, 4]
distance[goal[1]] = [1, 0, 1, 2, 1, 2, 3, 2, 3]
distance[goal[2]] = [2, 1, 0, 3, 2, 1, 4, 3, 2]
distance[goal[3]] = [1, 2, 3, 0, 1, 2, 1, 2, 3]
distance[goal[4]] = [2, 1, 2, 1, 0, 1, 2, 1, 2]
distance[goal[5]] = [3, 2, 1, 2, 1, 0, 3, 2, 1]
distance[goal[6]] = [2, 3, 4, 1, 2, 3, 0, 1, 2]
distance[goal[7]] = [3, 2, 3, 2, 1, 2, 1, 0, 1]
distance[goal[8]] = [4, 3, 2, 3, 2, 1, 2, 1, 0]
return distance
# Test
i = 1
print
for inst in instructions(solve_eight_puzzle((1,2,3,4,5,6,7,0,1),(1,2,3,4,0,7,6,5,1))):
print i, inst
i += 1
raw_input()
18 de Fevereiro de 2009 às 12:29
Thiago
O problema 8 puzzle é um quebra cabeça em que temos um tabuleiro 3 por 3 com 8 quadrados deslizantes e um espaço em branco. Dada uma posição inicial dos quadrados, pede-se para chegar em uma outra posição qualquer considerando que:
- Os quadrados podem ser deslizados para ocuparem a posição previamente em branco.
- Movimentos diagonais são proibidos.
- As peças só podem ser deslizadas, isto é, não pode-se tirá-las do tabuleiro.
Estava jogando o ótimo Professor Layton and the Curious Village quando emperrei num dos puzzles, que é um 8 puzzle (Puzzle 107: A Worm’s Dream). Depois de milhares de movimentos, desisti e resolvi escrever um programa para resolver o problema para mim, hehe. Apresento a solução abaixo, escrita em Python 2.5.
Adotei a abordagem mais simples, é uma busca em largura sem heurística no grafo onde os vértices são as diversas configurações do tabuleiro. Primeiro implementei a busca como uma função recursiva, mas estava estourando a pilha (Stack Overflow) então reescrevi a função de forma iterativa.
Conseguem ver como ela funciona? O que pode ser feito para melhorar a performance?
Alguém tem uma idéia melhor para como armazenar a seqüência de movimentos que o jogador tem que fazer?
This Python 2.5 program solves the 8 puzzle. It uses a simple breadth first search algorithm in a graph where the vertices are game board snapshots.
Can you see how it works? How can the performance be improved? Does someone have a better idea of how the answer should be stored or presented?
"""
This is a solver for the 8 sliders puzzle.
A state is a snapshot of the game board. It is represented by a list of
9 items, eg. [0,1,2,3,4,5,6,7,8]. The positions in the list map to the
following positions on the board:
0 1 2
3 4 5
6 7 8
We assume the square labelled 0 is the empty square. It is possible
to have more of the same number on the board.
"""
""" The allowed moves in the game. For example, 0:[1,3] means that
a square in position zero can be swapped with the square in position one
or the square in position three.
"""
SWAPS = {0:[1,3],
1:[0,2,4],
2:[1,5],
3:[0,4,6],
4:[1,3,5,7],
5:[2,4,8],
6:[3,7],
7:[4,6,8],
8:[5,7]}
def solve_eight_puzzle(begin, goal):
openlist = [begin]
closedlist = []
previous = {tuple(begin):None}
while len(openlist) > 0:
state = openlist.pop(0)
closedlist.append(state)
if state == goal:
s = tuple(goal)
path = []
while previous[s] is not None:
path.append(s)
s = previous[s]
path.append(s)
path.reverse()
return path
nextstates = [s for s in possible_moves(state) if s not in closedlist]
for next in nextstates:
previous[tuple(next)] = tuple(state)
openlist.extend(nextstates)
return None
def possible_moves(state):
izero = state.index(0)
swaps = SWAPS[izero]
new_states = []
for swap in swaps:
new_state = state[:]
new_state[izero] = state[swap]
new_state[swap] = state[izero]
new_states.append(new_state)
return new_states
# Test
print solve_eight_puzzle([0,1,3,4,2,5,7,8,6],[1,2,3,4,5,6,7,8,0])
17 de Fevereiro de 2009 às 17:27
Thiago
Hoje eu recebi a tarefa de enviar para o cliente do projeto em que trabalho os requisitos mínimos para rodar a aplicação desktop que desenvolvi. Como nunca havia feito isso antes, fiquei em dúvida sobre como proceder para determinar esses requisitos. Acabei coletando os requisitos mínimos para rodar a versão de Java que uso no desenvolvimento da aplicação (1.4.2) e os incrementei um pouco. De qualquer forma, ficou a dúvida: existe uma metodologia para determinar os requisitos mínimos de uma aplicação?
5 de Agosto de 2008 às 10:45
Matheus
Curioso código em Java que encontrei num programa no trabalho.
Sabendo que DeltaY é um int, explique porque:
1) O código funciona
2) O autor fez isso
BAD WAY
int Diametro = Math.round(Math.round(0.9*DeltaY));
GOOD WAY
int Diametro = Math.round(0.9f*DeltaY);
15 de Fevereiro de 2008 às 14:59
Thiago
Um código simples que usei para copiar um arquivo (na verdade, uso para copiar de um InputStream para um OutputStream):
InputStream in = (...)
OutputStream out = (...)
for (int b = in.read(); b != -1; out.write(b), b = in.read());
17 de Setembro de 2007 às 13:48
Thiago
Quines são programas que imprimem o seu próprio código fonte.
Sempre quis escrever um e finalmente o fiz, em Python.
O código está a seguir. Alguém mais quer tentar?
a = """a = UIA
c = chr(34) * 3
print a.replace("UIA", (c + a + c), 1)"""
c = chr(34) * 3
print a.replace("UIA", (c + a + c), 1)
Pelo menos em Python, usando a biblioteca, fica fácil.
6 de Setembro de 2007 às 09:11
Thiago
Gente, não sei se estão sabendo da lei do Simples Nacional. Os sistemas são desenvolvidos aqui no Serpro, mas os prazos legais para construção deles são absurdos!!!
Veja semana passada: meu chefe abriu um projeto na quarta-feira que teria que estar pronto na sexta. Incluindo tudo que se espera de um estabelecimento certificado CMMI2: requisitos, implementação, testes, homologação e implantação.
Hoje foi pior.
Meu chefe acabou de abrir um projeto devido a uma resolução do comitê que coordena o Simples Nacional. Que foi feita ontem. E que deve ser implantada hoje.
Acabei de fazer os requisitos e estamos mandando para aprovação. Ainda temos que implementar, testar, homologar e implantar hoje ainda. HOJE!
Tá uma correria aqui…
31 de Julho de 2007 às 11:16
Thiago
Todo programador sabe (ou deveria saber) o trabalho que dá manter um programa compatível. Compatível consigo mesmo, com as versões anteriores, com as diversas máquinas dos usuários, com a decisão tomada apressadamente há 10 anos atrás por alguém que nem faz parte da equipe mais. Ao trabalhar aqui no Serpro dá para ter um gostinho do que o pessoal da Microsoft passa.
Bom, hoje a questão é o XPath. Um programa nosso funcionou na máquina de um colega meu, mas não na minha. O Eclipse não conseguiu encontrar um pacote. A diferença entre nossas configurações é que ele usa a JRE 5.0 e eu a 1.4 para implementar. O problema é: o pacote onde estão as classes do XPath é diferente no Java 1.4 e no 5.0.
Como o código tem que rodar nessas duas versões da máquina virtual, a saída que arranjei foi carregar as classes por reflexão. Isto é: tente com um nome de pacote e se não der, use o outro.
Bom, pelo menos não tenho mais que programar para OS/2.
5 de Junho de 2007 às 18:12
Thiago
Mais informações aqui.
11 de Maio de 2007 às 10:06
Thiago
Publicações anteriores