I have the following binary clock script code below. The code works fine, but I want to ensure the clock syncs every few hours or so. I realize that the code takes the system time, but would prefer if it reached out to a ntp site to get/correct the time. Can someone please assist?
#!/usr/bin/env python3
A binary clock: displays the current time (HHMMSS) in binary-coded decimal.'''
import time
from itertools import zip_longest
from gpiozero import LED
def main():
# H8 M8 S8
leds = [ None, LED(14), None, LED(24), None, LED(12),
# H40 H4 M40 M4 S40 S4
LED(22), LED(15), LED(11), LED(25), LED(13), LED(16),
# H20 H2 M20 M2 S20 S2
LED(10), LED(18), LED(5), LED(8), LED(19), LED(20),
# H10 H1 M10 M1 S10 S1
LED(9), LED(23), LED(6), LED(7), LED(26), LED(21)]
try:
while True:
t = time.strftime('%H%M%S')
print(t)
b = bcd(t)
s = vertical_strings(b)
print(s + '\n')
light(s, leds)
time.sleep(0.2)
except KeyboardInterrupt:
print('done')
# bcd :: iterable(characters '0'-'9') -> [str]
def bcd(digits):
'Convert a string of decimal digits to binary-coded-decimal.'
def bcdigit(d):
'Convert a decimal digit to BCD (4 bits wide).'
# [2:] strips the '0b' prefix added by bin().
return bin(d)[2:].rjust(4, '0')
return (bcdigit(int(d)) for d in digits)
# vertical_strings :: iterable(str) -> str
def vertical_strings(strings):
'Orient an iterable of strings vertically: one string per column.'
iters = [iter(s) for s in strings]
concat = ''.join
return ''.join(map(concat,
zip_longest(*iters, fillvalue=' ')))
def light(strings, leds):
x = 0
for l in strings:
if l == '1' and leds[x] is not None:
leds[x].on()
elif l == '0' and leds[x] is not None:
leds[x].off()
x = x + 1
if __name__ == '__main__':
main()
Related
in raspberry pi pico board when i tried to connect 3v3 with 3v3 of raspberry pi pico , gnd to gnd of raspberry pi pico and dat to g16 and ran this belo code on thonny micropython .
main temp_hum_DHT_code.py
from machine import Pin
import time
from dht import DHT11, InvalidChecksum
sensor = DHT11(Pin(16, Pin.OUT, Pin.PULL_DOWN))
while True:
temp = sensor.temperature
humidity = sensor.humidity
print("Temperature: {}°C Humidity: {:.0f}% ".format(temp, humidity))
time.sleep(2)
dht.py
import array
import micropython
import utime
from machine import Pin
from micropython import const
class InvalidChecksum(Exception):
pass
class InvalidPulseCount(Exception):
pass
MAX_UNCHANGED = const(100)
MIN_INTERVAL_US = const(200000)
HIGH_LEVEL = const(50)
EXPECTED_PULSES = const(84)
class DHT11:
_temperature: float
_humidity: float
def __init__(self, pin):
self._pin = pin
self._last_measure = utime.ticks_us()
self._temperature = -1
self._humidity = -1
def measure(self):
current_ticks = utime.ticks_us()
if utime.ticks_diff(current_ticks, self._last_measure) < MIN_INTERVAL_US and (
self._temperature > -1 or self._humidity > -1
):
# Less than a second since last read, which is too soon according
# to the datasheet
return
self._send_init_signal()
pulses = self._capture_pulses()
buffer = self._convert_pulses_to_buffer(pulses)
self._verify_checksum(buffer)
self._humidity = buffer[0] + buffer[1] / 10
self._temperature = buffer[2] + buffer[3] / 10
self._last_measure = utime.ticks_us()
#property
def humidity(self):
self.measure()
return self._humidity
#property
def temperature(self):
self.measure()
return self._temperature
def _send_init_signal(self):
self._pin.init(Pin.OUT, Pin.PULL_DOWN)
self._pin.value(1)
utime.sleep_ms(50)
self._pin.value(0)
utime.sleep_ms(18)
#micropython.native
def _capture_pulses(self):
pin = self._pin
pin.init(Pin.IN, Pin.PULL_UP)
val = 1
idx = 0
transitions = bytearray(EXPECTED_PULSES)
unchanged = 0
timestamp = utime.ticks_us()
while unchanged < MAX_UNCHANGED:
if val != pin.value():
if idx >= EXPECTED_PULSES:
raise InvalidPulseCount(
"Got more than {} pulses".format(EXPECTED_PULSES)
)
now = utime.ticks_us()
transitions[idx] = now - timestamp
timestamp = now
idx += 1
val = 1 - val
unchanged = 0
else:
unchanged += 1
pin.init(Pin.OUT, Pin.PULL_DOWN)
if idx != EXPECTED_PULSES:
raise InvalidPulseCount(
"Expected {} but got {} pulses".format(EXPECTED_PULSES, idx)
)
return transitions[4:]
def _convert_pulses_to_buffer(self, pulses):
"""Convert a list of 80 pulses into a 5 byte buffer
The resulting 5 bytes in the buffer will be:
0: Integral relative humidity data
1: Decimal relative humidity data
2: Integral temperature data
3: Decimal temperature data
4: Checksum
"""
# Convert the pulses to 40 bits
binary = 0
for idx in range(0, len(pulses), 2):
binary = binary << 1 | int(pulses[idx] > HIGH_LEVEL)
# Split into 5 bytes
buffer = array.array("B")
for shift in range(4, -1, -1):
buffer.append(binary >> shift * 8 & 0xFF)
return buffer
def _verify_checksum(self, buffer):
# Calculate checksum
checksum = 0
for buf in buffer[0:4]:
checksum += buf
if checksum & 0xFF != buffer[4]:
raise InvalidChecksum()
.............................................................................................................................................................
You are given an array nums consisting of non-negative integers. You are also given a queries array, where queries[i] = [xi, mi].
The answer to the ith query is the maximum bitwise XOR value of xi and any element of nums that does not exceed mi. In other words, the answer is max(nums[j] XOR xi) for all j such that nums[j] <= mi. If all elements in nums are larger than mi, then the answer is -1.
Return an integer array answer where answer.length == queries.length and answer[i] is the answer to the ith query.
This python solution uses Trie, but still LeetCode shows TLE?
import operator
class TrieNode:
def __init__(self):
self.left=None
self.right=None
class Solution:
def insert(self,head,x):
curr=head
for i in range(31,-1,-1):
val = (x>>i) & 1
if val==0:
if not curr.left:
curr.left=TrieNode()
curr=curr.left
else:
curr=curr.left
else:
if not curr.right:
curr.right=TrieNode()
curr=curr.right
else:
curr=curr.right
def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
res=[-10]*len(queries)
nums.sort()
for i in range(len(queries)):
queries[i].append(i)
queries.sort(key=operator.itemgetter(1))
head=TrieNode()
for li in queries:
max=0
xi,mi,index=li[0],li[1],li[2]
m=2**31
node = head
pos=0
if mi<nums[0]:
res[index]=-1
continue
for i in range(pos,len(nums)):
if mi<nums[i]:
pos=i
break
self.insert(node,nums[i])
node=head
for i in range(31,-1,-1):
val=(xi>>i)&1
if val==0:
if node.right:
max+=m
node=node.right
else:
node=node.left
else:
if node.left:
max+=m
node=node.left
else:
node=node.right
m>>=1
res[index]=max
return -1
here is alternative Trie implement to solve this problem:
[Notes: 1) max(x XOR y for y in A); 2) do the greedy on MSB bit; 3) sort the queries]
class Trie:
def __init__(self):
self.root = {}
def add(self, n):
p = self.root
for bitpos in range(31, -1, -1):
bit = (n >> bitpos) & 1
if bit not in p:
p[bit] = {}
p = p[bit]
def query(self, n):
p = self.root
ret = 0
if not p:
return -1
for bitpos in range(31, -1, -1):
bit = (n >> bitpos) & 1
inverse = 1 - bit
if inverse in p:
p = p[inverse]
ret |= (1 << bitpos)
else:
p = p[bit]
return ret
class Solution:
def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
n = len(nums)
trie = Trie()
q = sorted(enumerate(queries), key = lambda x: x[1][1])
nums.sort()
res = [-1] * len(queries)
i = 0
for index, (x, m) in q:
while i < n and nums[i] <= m:
trie.add(nums[i])
i += 1
res[index] = trie.query(x)
return res
The problem is that you're building a fresh Trie for each query. And to make matters worse, use linear search to find the maximum value <= mi in nums. You'd be better off by simply using
max((n for n in nums if n <= mi), key=lambda n: n^xi, default=-1)
The solution here would be to build the trie right at the start and simply filter for values smaller than mi using that trie:
import math
import bisect
def dump(t, indent=''):
if t is not None:
print(indent, "bit=", t.bit, "val=", t.val, "lower=", t.lower)
dump(t.left, indent + '\tl')
dump(t.right, indent + '\tr')
class Trie:
def __init__(self, bit, val, lower):
self.bit = bit
self.val = val
self.lower = lower
self.left = None
self.right = None
def solve(self, mi, xi):
print('-------------------------------------------')
print(self.bit, "mi(b)=", (mi >> self.bit) & 1, "xi(b)=", (xi >> self.bit) & 1, "mi=", mi, "xi=", xi)
dump(self)
if self.val is not None:
# reached a leave of the trie => found matching value
print("Leaf")
return self.val
if mi & (1 << self.bit) == 0:
# the maximum has a zero-bit at this position => all values in the right subtree are > mi
print("Left forced by max")
return -1 if self.left is None else self.left.solve(mi, xi)
# pick based on xor-value if possible
if (xi >> self.bit) & 1 == 0 and self.right is not None and (mi > self.right.lower or mi == ~0):
print("Right preferred by xi")
return self.right.solve(mi, xi)
elif (xi >> self.bit) & 1 == 1 and self.left is not None:
print("Left preferred by xi")
return self.left.solve(~0, xi)
# pick whichever is available
if self.right is not None and (mi > self.right.lower or mi == ~0):
print("Only right available")
return self.right.solve(mi, xi)
elif self.left is not None:
print("Only left available")
return self.left.solve(~0, xi)
else:
print("None available")
return -1
def build_trie(nums):
nums.sort()
# msb of max(nums)
max_bit = int(math.log(nums[-1], 2)) # I'll just assume that nums is never empty
print(max_bit)
def node(start, end, bit, template):
print(start, end, bit, template, nums[start:end])
if end - start == 1:
# reached a leaf
return Trie(0, nums[start], nums[start])
elif start == end:
# a partition without values => no Trie-node
return None
# find pivot for partitioning based on bit-value of specified position (bit)
part = bisect.bisect_left(nums, template | (1 << bit), start, end)
print(part)
# build nodes for paritioning
res = Trie(bit, None, nums[start])
res.left = node(start, part, bit - 1, template)
res.right = node(part, end, bit - 1, template | (1 << bit))
return res
return node(0, len(nums), max_bit, 0)
class Solution:
def maximizeXor(self, nums: List[int], queries: List[List[int]]) -> List[int]:
trie = build_trie(nums)
return [trie.solve(mi if mi <= nums[-1] else ~0, xi) for xi, mi in queries]
I've been a bit lazy and simply used ~0 to signify that the maximum can be ignored since all values in the subtree are smaller than mi. The basic idea is that ~0 & x == x is true for any integer x. Not quite as simple as #DanielHao's answer, but capable of handling streams of queries.
I built 5-layer neural network by using tensorflow.
I have a problem to get reproducible results (or stable results).
I found similar questions regarding reproducibility of tensorflow and the corresponding answers, such as How to get stable results with TensorFlow, setting random seed
But the problem is not solved yet.
I also set random seed like the following
tf.set_random_seed(1)
Furthermore, I added seed options to every random function such as
b1 = tf.Variable(tf.random_normal([nHidden1], seed=1234))
I confirmed that the first epoch shows the identical results, but not identical from the second epoch little by little.
How can I get the reproducible results?
Am I missing something?
Here is a code block I use.
def xavier_init(n_inputs, n_outputs, uniform=True):
if uniform:
init_range = tf.sqrt(6.0 / (n_inputs + n_outputs))
return tf.random_uniform_initializer(-init_range, init_range, seed=1234)
else:
stddev = tf.sqrt(3.0 / (n_inputs + n_outputs))
return tf.truncated_normal_initializer(stddev=stddev, seed=1234)
import numpy as np
import tensorflow as tf
import dataSetup
from scipy.stats.stats import pearsonr
tf.set_random_seed(1)
x_train, y_train, x_test, y_test = dataSetup.input_data()
# Parameters
learningRate = 0.01
trainingEpochs = 1000000
batchSize = 64
displayStep = 100
thresholdReduce = 1e-6
thresholdNow = 0.6
#dropoutRate = tf.constant(0.7)
# Network Parameter
nHidden1 = 128 # number of 1st layer nodes
nHidden2 = 64 # number of 2nd layer nodes
nInput = 24 #
nOutput = 1 # Predicted score: 1 output for regression
# save parameter
modelPath = 'model/model_layer5_%d_%d_mini%d_lr%.3f_noDrop_rollBack.ckpt' %(nHidden1, nHidden2, batchSize, learningRate)
# tf Graph input
X = tf.placeholder("float", [None, nInput])
Y = tf.placeholder("float", [None, nOutput])
# Weight
W1 = tf.get_variable("W1", shape=[nInput, nHidden1], initializer=xavier_init(nInput, nHidden1))
W2 = tf.get_variable("W2", shape=[nHidden1, nHidden2], initializer=xavier_init(nHidden1, nHidden2))
W3 = tf.get_variable("W3", shape=[nHidden2, nHidden2], initializer=xavier_init(nHidden2, nHidden2))
W4 = tf.get_variable("W4", shape=[nHidden2, nHidden2], initializer=xavier_init(nHidden2, nHidden2))
WFinal = tf.get_variable("WFinal", shape=[nHidden2, nOutput], initializer=xavier_init(nHidden2, nOutput))
# biases
b1 = tf.Variable(tf.random_normal([nHidden1], seed=1234))
b2 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
b3 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
b4 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
bFinal = tf.Variable(tf.random_normal([nOutput], seed=1234))
# Layers for dropout
L1 = tf.nn.relu(tf.add(tf.matmul(X, W1), b1))
L2 = tf.nn.relu(tf.add(tf.matmul(L1, W2), b2))
L3 = tf.nn.relu(tf.add(tf.matmul(L2, W3), b3))
L4 = tf.nn.relu(tf.add(tf.matmul(L3, W4), b4))
hypothesis = tf.add(tf.matmul(L4, WFinal), bFinal)
print "Layer setting DONE..."
# define loss and optimizer
cost = tf.reduce_mean(tf.square(hypothesis - Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learningRate).minimize(cost)
# Initialize the variable
init = tf.initialize_all_variables()
# save op to save and restore all the variables
saver = tf.train.Saver()
with tf.Session() as sess:
# initialize
sess.run(init)
print "Initialize DONE..."
# Training
costPrevious = 100000000000000.0
best = float("INF")
totalBatch = int(len(x_train)/batchSize)
print "Total Batch: %d" %totalBatch
for epoch in range(trainingEpochs):
#print "EPOCH: %04d" %epoch
avgCost = 0.
for i in range(totalBatch):
np.random.seed(i+epoch)
randidx = np.random.randint(len(x_train), size=batchSize)
batch_xs = x_train[randidx,:]
batch_ys = y_train[randidx,:]
# Fit traiing using batch data
sess.run(optimizer, feed_dict={X:batch_xs, Y:batch_ys})
# compute average loss
avgCost += sess.run(cost, feed_dict={X:batch_xs, Y:batch_ys})/totalBatch
# compare the current cost and the previous
# if current cost > the previous
# just continue and make the learning rate half
#print "Cost: %1.8f --> %1.8f at epoch %05d" %(costPrevious, avgCost, epoch+1)
if avgCost > costPrevious + .5:
#sess.run(init)
load_path = saver.restore(sess, modelPath)
print "Cost increases at the epoch %05d" %(epoch+1)
print "Cost: %1.8f --> %1.8f" %(costPrevious, avgCost)
continue
costNow = avgCost
reduceCost = abs(costPrevious - costNow)
costPrevious = costNow
#Display logs per epoch step
if costNow < best:
best = costNow
bestMatch = sess.run(hypothesis, feed_dict={X:x_test})
# model save
save_path = saver.save(sess, modelPath)
if epoch % displayStep == 0:
print "step {}".format(epoch)
pearson = np.corrcoef(bestMatch.flatten(), y_test.flatten())
print 'train loss = {}, current loss = {}, test corrcoef={}'.format(best, costNow, pearson[0][1])
if reduceCost < thresholdReduce or costNow < thresholdNow:
print "Epoch: %04d, Cost: %.9f, Prev: %.9f, Reduce: %.9f" %(epoch+1, costNow, costPrevious, reduceCost)
break
print "Optimization Finished"
It seems that your results are perhaps not reproducible because you are using Saver to write/restore from checkpoint each time? (i.e. the second time that you run the code, the variable values aren't initialized using your random seed -- they are restored from your previous checkpoint)
Please trim down your code example to just the code necessary to reproduce irreproducibility.
Below I've posted the code to a non-working "divide and conquer" multiplication method in ruby(with debug prints). I cannot tell if its broken code, or a quirk in Ruby like how the L-shift(<<) operator doesn't push bits into the bit-bucket; this is unexpected compared to similar operations in C++.
Is it broken code (doesn't match the original algorithm) or unexpected behavior?
Pseudo code for original algorithm
def multiply(x,y,n, level)
#print "Level #{level}\n"
if n == 1
#print "\tx[#{x.to_s(2)}][#{y.to_s(2)}]\n\n"
return x*y
end
mask = 2**n - 2**(n/2)
xl = x >> (n / 2)
xr = x & ~mask
yl = y >> (n / 2)
yr = y & ~mask
print " #{n} | x = #{x.to_s(2)} = L[#{xl.to_s(2)}][#{xr.to_s(2)}]R \n"
print " #{n} | y = #{y.to_s(2)} = L[#{yl.to_s(2)}][#{yr.to_s(2)}]R \n"
#print "\t[#{xl.to_s(2)}][#{yr.to_s(2)}]\n"
#print "\t[#{xr.to_s(2)}][#{yr.to_s(2)}]\n"
#print "\t([#{xl.to_s(2)}]+[#{xr.to_s(2)}])([#{yl.to_s(2)}]+[#{yr.to_s(2)}])\n\n"
p1 = multiply( xl, yl, n/2, level+1)
p2 = multiply( xr, yr, n/2, level+1)
p3 = multiply( xl+xr, yl+yr, n/2, level+1)
return p1 * 2**n + (p3 - p1 - p2) * 2**(n/2) + p2
end
x = 21
y = 22
print "x = #{x} = #{x.to_s(2)}\n"
print "y = #{y} = #{y.to_s(2)}\n"
print "\nDC_multiply\t#{x}*#{y} = #{multiply(x,y,8, 1)} \nregular\t#{x}*#{y} = #{x*y}\n\n "
I am not familiar with the divide and conquer algorithm but i don't think it contains parts you can't do in Ruby.
Here is a quick attempt:
def multiplb(a,b)
#Break recursion when a or b has one digit
if a < 10 || b < 10
a * b
else
#Max number of digits of a and b
n = [a.to_s.length, b.to_s.length].max
# Steps to split numbers to high and low digits sub-numbers
# (1) to_s.split('') => Converting digits to string then arrays to ease splitting numbers digits
# (2) each_slice => Splitting both numbers to high(left) and low(right) digits groups
# (3) to_a , map, join, to_i => Simply returning digits to numbers
al, ar = a.to_s.split('').each_slice(n/2).to_a.map(&:join).map(&:to_i)
bl, br = b.to_s.split('').each_slice(n/2).to_a.map(&:join).map(&:to_i)
#Recursion
p1 = multiplb(al, bl)
p2 = multiplb(al + ar, bl + br)
p3 = multiplb(ar, br)
p1 * (10**n) + (p2 - p1 - p3) * (10**(n/2)) + p3
end
end
#Test
puts multiplb(1980, 2315)
# => 4583700 yeah that's correct :)
Here are some references to further explain part of the code:
Finding max of numbers => How do you find a min / max with Ruby?
Spliting an array to half => Splitting an array into equal parts in ruby
Turning a fixnum into array => Turning long fixed number to array Ruby
Hope it hepls !
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Here's an interesting problem to solve in minimal amounts of code. I expect the recursive solutions will be most popular.
We have a maze that's defined as a map of characters, where = is a wall, a space is a path, + is your starting point, and # is your ending point. An incredibly simple example is like so:
====
+ =
= ==
= #
====
Can you write a program to find the shortest path to solve a maze in this style, in as little code as possible?
Bonus points if it works for all maze inputs, such as those with a path that crosses over itself or with huge numbers of branches. The program should be able to work for large mazes (say, 1024x1024 - 1 MB), and how you pass the maze to the program is not important.
The "player" may move diagonally. The input maze will never have a diagonal passage, so your base set of movements will be up, down, left, right. A diagonal movement would be merely looking ahead a little to determine if a up/down and left/right could be merged.
Output must be the maze itself with the shortest path highlighted using the asterisk character (*).
Works for any (fixed-size) maze with a minimum of CPU cycles (given a big enough BFG2000). Source size is irrelevant since the compiler is incredibly efficient.
while curr.x != target.x and curr.y != target.y:
case:
target.x > curr.x : dx = 1
target.x < curr.x : dx = -1
else : dx = 0
case:
target.y > curr.y : dy = 1
target.y < curr.y : dy = -1
else : dy = 0
if cell[curr.x+dx,curr.y+dy] == wall:
destroy cell[curr.x+dx,curr.y+dy] with patented BFG2000 gun.
curr.x += dx
curr.y += dy
survey shattered landscape
F#, not very short (72 non-blank lines), but readable. I changed/honed the spec a bit; I assume the original maze is a rectangle fully surrounded by walls, I use different characters (that don't hurt my eyes), I only allow orthogonal moves (not diagonal). I only tried one sample maze. Except for a bug about flipping x and y indicies, this worked the first time, so I expect it is right (I've done nothing to validate it other than eyeball the solution on the one sample I gave it).
open System
[<Literal>]
let WALL = '#'
[<Literal>]
let OPEN = ' '
[<Literal>]
let START = '^'
[<Literal>]
let END = '$'
[<Literal>]
let WALK = '.'
let sampleMaze = #"###############
# # # #
# ^# # # ### #
# # # # # # #
# # # #
############ #
# $ #
###############"
let lines = sampleMaze.Split([|'\r';'\n'|], StringSplitOptions.RemoveEmptyEntries)
let width = lines |> Array.map (fun l -> l.Length) |> Array.max
let height = lines.Length
type BestInfo = (int * int) list * int // path to here, num steps
let bestPathToHere : BestInfo option [,] = Array2D.create width height None
let mutable startX = 0
let mutable startY = 0
for x in 0..width-1 do
for y in 0..height-1 do
if lines.[y].[x] = START then
startX <- x
startY <- y
bestPathToHere.[startX,startY] <- Some([],0)
let q = new System.Collections.Generic.Queue<_>()
q.Enqueue((startX,startY))
let StepTo newX newY (path,count) =
match lines.[newY].[newX] with
| WALL -> ()
| OPEN | START | END ->
match bestPathToHere.[newX,newY] with
| None ->
bestPathToHere.[newX,newY] <- Some((newX,newY)::path,count+1)
q.Enqueue((newX,newY))
| Some(_,oldCount) when oldCount > count+1 ->
bestPathToHere.[newX,newY] <- Some((newX,newY)::path,count+1)
q.Enqueue((newX,newY))
| _ -> ()
| c -> failwith "unexpected maze char: '%c'" c
while not(q.Count = 0) do
let x,y = q.Dequeue()
let (Some(path,count)) = bestPathToHere.[x,y]
StepTo (x+1) (y) (path,count)
StepTo (x) (y+1) (path,count)
StepTo (x-1) (y) (path,count)
StepTo (x) (y-1) (path,count)
let mutable endX = 0
let mutable endY = 0
for x in 0..width-1 do
for y in 0..height-1 do
if lines.[y].[x] = END then
endX <- x
endY <- y
printfn "Original maze:"
printfn "%s" sampleMaze
let bestPath, bestCount = bestPathToHere.[endX,endY].Value
printfn "The best path takes %d steps." bestCount
let resultMaze = Array2D.init width height (fun x y -> lines.[y].[x])
bestPath |> List.tl |> List.iter (fun (x,y) -> resultMaze.[x,y] <- WALK)
for y in 0..height-1 do
for x in 0..width-1 do
printf "%c" resultMaze.[x,y]
printfn ""
//Output:
//Original maze:
//###############
//# # # #
//# ^# # # ### #
//# # # # # # #
//# # # #
//############ #
//# $ #
//###############
//The best path takes 27 steps.
//###############
//# # #....... #
//# ^# #.# ###. #
//# .# #.# # #. #
//# .....# #. #
//############. #
//# $....... #
//###############
Python
387 Characters
Takes input from stdin.
import sys
m,n,p=sys.stdin.readlines(),[],'+'
R=lambda m:[r.replace(p,'*')for r in m]
while'#'in`m`:n+=[R(m)[:r]+[R(m)[r][:c]+p+R(m)[r][c+1:]]+R(m)[r+1:]for r,c in[(r,c)for r,c in[map(sum,zip((m.index(filter(lambda i:p in i,m)[0]),[w.find(p)for w in m if p in w][0]),P))for P in zip((-1,0,1,0),(0,1,0,-1))]if 0<=r<len(m)and 0<=c<len(m[0])and m[r][c]in'# ']];m=n.pop(0)
print''.join(R(m))
I did this sort of thing for a job interview once (it was a pre-interview programming challenge)
Managed to get it working to some degree of success and it's a fun little challenge.