JavaScript
//let cave=['start-A','start-b','A-c','A-b','b-d','A-end','b-end']
//let cave=['dc-end','HN-start','start-kj','dc-start','dc-HN','LN-dc','HN-end','kj-sa','kj-HN','kj-dc']
//let cave=['fs-end','he-DX','fs-he','start-DX','pj-DX','end-zg','zg-sl','zg-pj','pj-he','RW-he','fs-DX','pj-RW','zg-RW','start-pj','he-WI','zg-he','pj-fs','start-RW']
let cave=['QF-bw','end-ne','po-ju','QF-lo','po-start','XL-ne','bw-US','ne-lo','nu-ne','bw-po','QF-ne','ne-ju','start-lo','lo-XL','QF-ju','end-ju','XL-end','bw-ju','nu-start','lo-nu','nu-XL','xb-XL','XL-po']
let map={}
cave.forEach(sys=>{
let t=sys.split('-')
if(map.hasOwnProperty(t[0])){
map[t[0]].push(t[1])
}else{
map[t[0]] = [t[1]]
}
if(map.hasOwnProperty(t[1])){
map[t[1]].push(t[0])
}else{
map[t[1]] = [t[0]]
}
})
console.log(map)
let routes=[]
function isLowerCase(str)
{
return str == str.toLowerCase() && str != str.toUpperCase();
}
function findPath(path){
// console.log('>',path)
routes.splice(routes.findIndex(p=>p.join(',')==path.join(',')),1)
// console.log(routes.findIndex(p=>p.join(',')==path.join(',')))
// let change=false
let newp=[]
// console.log(path[path.length-1])
if(map.hasOwnProperty(path[path.length-1])){
map[path[path.length-1]].forEach(pos=>{
// console.log('>>',pos,isLowerCase(pos),path.indexOf(pos))
if(pos!='start' && ((isLowerCase(pos) && path.indexOf(pos)==-1)||(isLowerCase(pos) && path.indexOf(pos)!=-1 && new Set(path.slice(1).filter(a=>isLowerCase(a))).size == path.slice(1).filter(a=>isLowerCase(a)).length))||!isLowerCase(pos)){
newp.push([...path,pos])
routes.push([...path,pos])
// change=true
}
})
}
//routes.splice(routes.findIndex(p=>p.join(',')==path.join(',')),1)
// console.log('>>>',routes)
if(newp.length>0){
newp.forEach(r=>{
if(r[r.length-1]!='end'){
findPath([...r])
}
})
}
}
routes=[['start']]
findPath(['start'])
// console.log(routes)
console.log(routes.length)