5 changed files with 207 additions and 12 deletions
			
			
		@ -0,0 +1,161 @@ | 
				
			|||
#include <iostream> | 
				
			|||
#include <vector> | 
				
			|||
#include <complex> | 
				
			|||
#include <deque> | 
				
			|||
 | 
				
			|||
//#define ANIMATE
 | 
				
			|||
 | 
				
			|||
using namespace std; | 
				
			|||
 | 
				
			|||
struct Input { | 
				
			|||
    vector<vector<unsigned char>> map; | 
				
			|||
    unsigned width; | 
				
			|||
    unsigned height; | 
				
			|||
    complex<int> start; | 
				
			|||
    complex<int> end; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
complex<int> dirs[] = { | 
				
			|||
    complex<int>(1, 0), | 
				
			|||
    complex<int>(0, 1), | 
				
			|||
    complex<int>(-1, 0), | 
				
			|||
    complex<int>(0, -1) | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
Input parse() | 
				
			|||
{ | 
				
			|||
    Input data; | 
				
			|||
    auto &map = data.map; | 
				
			|||
    for (string line; getline(cin, line);) { | 
				
			|||
        vector<unsigned char> row; | 
				
			|||
        for (auto x : line) { | 
				
			|||
            switch (x) { | 
				
			|||
            case 'S': | 
				
			|||
                data.start = complex<int>(row.size(), map.size()); | 
				
			|||
                row.push_back('a' - 'a'); | 
				
			|||
                break; | 
				
			|||
            case 'E': | 
				
			|||
                data.end = complex<int>(row.size(), map.size()); | 
				
			|||
                row.push_back('z' - 'a'); | 
				
			|||
                break; | 
				
			|||
            default: row.push_back(x - 'a'); break; | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
        data.map.push_back(row); | 
				
			|||
    } | 
				
			|||
    data.width = map.front().size(); | 
				
			|||
    data.height = map.size(); | 
				
			|||
    return data; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
#ifdef ANIMATE | 
				
			|||
#include <fstream> | 
				
			|||
unsigned render_frame = 0; | 
				
			|||
void render(const Input &input, vector<vector<unsigned>> &dist, deque<complex<int>> &scan) | 
				
			|||
{ | 
				
			|||
    auto scan_map = (bool (*)[input.width])new bool[input.width * input.height](); | 
				
			|||
    for (auto &x : scan) { | 
				
			|||
        scan_map[x.imag()][x.real()] = true; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    char fname[] = "img/00000.pam"; | 
				
			|||
    sprintf(fname, "img/%05u.pam", render_frame++); | 
				
			|||
    auto file = ofstream(fname); | 
				
			|||
    file << "P7\n"; | 
				
			|||
    file << "WIDTH " << input.width << '\n'; | 
				
			|||
    file << "HEIGHT " << input.height << '\n'; | 
				
			|||
    file << "DEPTH 3\nMAXVAL 255\nTUPLTYPE RGB\nENDHDR\n"; | 
				
			|||
 | 
				
			|||
    unsigned maxdist = 0; | 
				
			|||
    for (unsigned y = 0; y < input.height; y++) { | 
				
			|||
        for (unsigned x = 0; x < input.width; x++) { | 
				
			|||
            unsigned d = dist[y][x]; | 
				
			|||
            if (d > maxdist) maxdist = d; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    for (unsigned y = 0; y < input.height; y++) { | 
				
			|||
        for (unsigned x = 0; x < input.width; x++) { | 
				
			|||
            uint32_t color = 0; | 
				
			|||
            color |= ((dist[y][x] * 0xFF / maxdist) & 0xFF) << 8; | 
				
			|||
            color |= input.map[y][x] * 0xFF / 26; | 
				
			|||
            if (scan_map[y][x]) color = 0xFF0000; | 
				
			|||
            file.write((char *)&color, 3); | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
    file.close(); | 
				
			|||
    delete scan_map; | 
				
			|||
} | 
				
			|||
#endif | 
				
			|||
 | 
				
			|||
vector<vector<unsigned>> calc_dist(const Input &input) | 
				
			|||
{ | 
				
			|||
    vector<vector<unsigned>> dist(input.height, vector<unsigned>(input.width)); | 
				
			|||
    auto &map = input.map; | 
				
			|||
 | 
				
			|||
    deque<complex<int>> scan; | 
				
			|||
    scan.push_back(input.end); | 
				
			|||
    dist[input.end.imag()][input.end.real()] = 1; | 
				
			|||
 | 
				
			|||
    while (!scan.empty()) { | 
				
			|||
        auto pos = scan.front(); | 
				
			|||
        unsigned pos_d = dist[pos.imag()][pos.real()]; | 
				
			|||
        unsigned pos_h = map[pos.imag()][pos.real()]; | 
				
			|||
        scan.pop_front(); | 
				
			|||
 | 
				
			|||
        for (auto dir : dirs) { | 
				
			|||
            auto newpos = pos + dir; | 
				
			|||
 | 
				
			|||
            // Make sure the new position is in-bounds
 | 
				
			|||
            if (newpos.imag() < 0 || newpos.imag() >= (int)input.height) continue; | 
				
			|||
            if (newpos.real() < 0 || newpos.real() >= (int)input.width) continue; | 
				
			|||
 | 
				
			|||
            // If the distance for this position has already been calculated,
 | 
				
			|||
            //  and is smaller than the current pos' distance, skip it.
 | 
				
			|||
            unsigned &newpos_d = dist[newpos.imag()][newpos.real()]; | 
				
			|||
            if (newpos_d && newpos_d <= pos_d + 1) continue; | 
				
			|||
 | 
				
			|||
            // Make sure the height difference isn't too big
 | 
				
			|||
            unsigned newpos_h = map[newpos.imag()][newpos.real()]; | 
				
			|||
            if ((int)pos_h - (int)newpos_h > 1) continue; | 
				
			|||
 | 
				
			|||
            // Otherwise, continue down this path
 | 
				
			|||
            newpos_d = pos_d + 1; | 
				
			|||
            scan.push_back(newpos); | 
				
			|||
        } | 
				
			|||
#ifdef ANIMATE | 
				
			|||
        render(input, dist, scan); | 
				
			|||
#endif | 
				
			|||
    } | 
				
			|||
    return dist; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsigned p1(const Input &input, const vector<vector<unsigned>> &dist) | 
				
			|||
{ | 
				
			|||
    unsigned end_dist = dist[input.start.imag()][input.start.real()]; | 
				
			|||
    if (end_dist) end_dist--; | 
				
			|||
    return end_dist; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsigned p2(const Input &input, const vector<vector<unsigned>> &dist) | 
				
			|||
{ | 
				
			|||
    unsigned smallest = dist[input.start.imag()][input.start.real()]; | 
				
			|||
    for (unsigned y = 0; y < input.height; y++) { | 
				
			|||
        for (unsigned x = 0; x < input.width; x++) { | 
				
			|||
            if (input.map[y][x] == 0) { | 
				
			|||
                unsigned d = dist[y][x]; | 
				
			|||
                if (d && d < smallest) smallest = d; | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
    if (smallest) smallest--; | 
				
			|||
    return smallest; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
int main() | 
				
			|||
{ | 
				
			|||
    auto input = parse(); | 
				
			|||
    auto dist = calc_dist(input); | 
				
			|||
    cout << p1(input, dist) << endl; | 
				
			|||
    cout << p2(input, dist) << endl; | 
				
			|||
} | 
				
			|||
								
									Binary file not shown.
								
							
						
					@ -0,0 +1,41 @@ | 
				
			|||
abcccccccccccccccccaaccccccccccccaaaaaaaacccccccccccaaaaaccccaaaaaaccaaaaaaaaaaaaaaaaaccccccccccccccccaaacccccaaaaaaaacccaaaccccccccccccccccccccccccccccccccccccccccccccccccccaaaaa | 
				
			|||
abccccccccccccccccaaacaacccccccccccaaaacccccccccccccaaaaaacccaaaaaaccaaaaaaaaaaaaaaaaaaaacccccccccaaacaaacccccaaaaaaaaaccaaaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa | 
				
			|||
abcccccccccccccccccaaaaacccccccccccaaaaaccccccccccccaaaaaaccccaaaacccaaaacccaaaaaaaaaaaaacccccccccaaaaaaaaaacccaaaaaaaaccaaaaccccccccccccccccccccccccccccccccccaaacccccccccccaaaaaa | 
				
			|||
abcccccccccccccccaaaaaacccccccccccaaacaaccaaccccccccaaaaaaccccaaaacccaaaccccaaaaaaaaaaaaaccccccccccaaaaaaaaaccaaaaaacccccaaacccccccccccccccccccccccccccccccccccaaaccccccccccccccaaa | 
				
			|||
abcccccccccccccccaaaaaaaacccccccccaacccacaaacaacccccccaaccccccaccaccccccccaaaaaaaaaaaaccccccccccccccaaaaaaacccaaaaaaacccccccccccccaacccccccccccccccccccccccccccaaaccccccccccccccaaa | 
				
			|||
abcccccccccccccccaacaaaaacccccccccccccccccaaaaacccccccccccccccccccccccccccaaaaaaaaaaaaccccccccccccccaaaaaaccccaaccaaacccccccccccaaaaaaccccccccccccccccccccccccccdccccccccccccccccaa | 
				
			|||
abccaacccccccaaacccaaacaccccccccccaaacccaaaaaaccccccccccccccccccccccccccccaaacccaaaaaacaaaaccccccccaaaaaaaccccccccaaacccccccccccaaaaaacccccccccccccccccllllllcccdddddcccccccccccccc | 
				
			|||
abaaaacccacccaaccccaacccccccccccccaaacccaaaaaaaacccccccccccccccccaaccccccccacccaaaaccccaaaaccccccccaaacaaaccccccccccccccccccccccaaaaaaccccccccccccccccllllllllldddddddddddccaaccccc | 
				
			|||
abaaaaccaaaaaaaacccccccccccccccaaaaaaaacaacaaaaacccccccccccccccccaaacccccccaaacaaccccccaaaacccccccccccccaaccccccccccccccccccccccaaaaaccccccccccccccccclllllllllldddddddddeeaaaccccc | 
				
			|||
abaaaccccaaaaaaaaccccccccaaacccaaaaaaaacccaaacccccccccccccccccaaaaaaaaccccccaaaaacccccccaacccccccccccccccccccccccccccccccccccccccaaaaccccaaaccccccccckllppppplllmmmmmmmdeeeeaaccccc | 
				
			|||
abaaaacccaaaaaaaaacccccaaaaaaccccaaaaaccccaaccccccccccccccccccaaaaaaaaccccccaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccaaaacccccccckklpppppppplmmmmmmmmmeeeeaccccc | 
				
			|||
abaaaacccaaaaaaaaacccccaaaaaacccaaaaaaccccccccaacccccccccccccccaaaaaaccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccaaaacccccccckkkppppppppqmmmmmmmmmmeeeaacccc | 
				
			|||
abaaaaaccaaaaaaaaccccccaaaaaacccaaaaaaccccccacaaaacccccccccccccaaaaaaccccccaaaaaaaaccccccccaaaaccccccccaaacccccccccccccccccccccccccccccccaaacccccccckkkpppuuuppqqqqqqqqmmmeeeeacccc | 
				
			|||
abacccccaaaaaaaccccccccaaaaaccccaccaaaccccccaaaaaacccccacccccccaaaaaaccccccaaaaaacaaaccccccaaaaccccccccaaaacccccccccccccccccccccccccccccccccccccccckkkpppuuuuuuqqqqqqqqqnnneeeccccc | 
				
			|||
abcccccccaccaaaccccccccaaaaacccccccccccccccccaaaacccaaaacccccccaacaaacccccccccaaacaaaaaccccaaaaccccccccaaaaccccccccccccccccccccccccccccccccccccccckkkkpppuuuuuuuqvvvvqqqnnneeeccccc | 
				
			|||
abcccccccccccaaacaaccccccccccccccccccccccccccaaaacccaaaaaacccccccccccccccccccccccaaaaaaccccaaacccccccccaaaccccccccccccccccccccccccccccccccccccccckkkkrrpuuuxxxuvvvvvvvqqnnneeeccccc | 
				
			|||
abcccccccccccccccaacaaaccccccccccccccccccccccaacaacccaaaaacccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccckkkkrrrruuxxxxuvvvvvvvqqnnneeeccccc | 
				
			|||
abcccccccccccccccaaaaacccccccccccccccccccccccccccaccaaaaacccccaaccccccccccccccccccaaaaaccccccccccccccccaaaccccccccccccccaaacccccccccccccccccccckkkkrrrruuuxxxxyyyyyvvvqqnnneecccccc | 
				
			|||
abcccccccccccccaaaaaacccccccccccaacaacccccccccccaaaaaaaaacccacaaaacaaccaaccccccccaaacaaccccccccccaaccccaaaaaacccaacaacccaaacacccccccccccccccccjjkkrrrruuuuuxxxyyyyyvvqrqnneffcccccc | 
				
			|||
abcccccccccccccaaaaaaaacccaaacccaaaaaccccccaacccaaaaaaaaacccaaaaaacaaaaaaccccccccaaacaaacccccccaaaaaacaaaaaaacccaaaaacaaaaaaaaccccccccccccccccjjjrrrtttuuxxxxxyyyyyvvrrnnnfffcccccc | 
				
			|||
SbccccccccccccccccaaaaacccaaaaccaaaaaaccccaaaaaacaaaaaaaaacccaaaacccaaaaaccccccccaaaaaaacccccccaaaaaaaaaaaaaaccaaaaaccaaaaaaaaccccccccccccccccjjjrrrtttxxxEzzzzyyyvvrrrnnnfffcccccc | 
				
			|||
abccccccccccaaaccaaccaacccaaaaccaaaaaacccccaaaaacaaaaaaaaacccaaaaccaaaaaacccccccccaaaaaaccccccccaaaacaaaaaaacccaaaaaaccaaaaaacccccccccccccccccjjjrrrtttxxxxxyyyyyyvvrrrnnnfffcccccc | 
				
			|||
abcccccccccaaaaccaacccccccaaacccaaaaaacccaaaaaaaaaaaaaaaaacccaacacaaaaaaaacccccaaaaaaaacccccccccaaaacccaaaaaaccccaaaacccaaaaacccccccccccccccccjjjrrrtttxxxxxyyyyyyywvrrnnnfffcccccc | 
				
			|||
abcccccccccaaaacccccccccccccccccccaaaccccaaaaaaaaaaaaaaaaaacccccccaaaaaaaacccccaaaaaaaaaccccccccaccacccaaaaaaccccacccccaaaaaacccccccccccccccccjjjrrrrttttxxxyyyyyyywwrrroooffcccccc | 
				
			|||
abccccccccccaaaccccccccccccccccccccccccccaaaaaaaaaccaaaaaaaccccccccccaaccccccccaaaaaaaaaaccccccccccccccaacccccccccccccccaaccccccccccccccccccccjjjjqqqqttttxxyywwwwwwwwrrooofffccccc | 
				
			|||
abcccccccccccccccccccccccccccccccccccccccccaaacacccccaaaaccccccccccccaacccccccccccaaacaaacccccccccccccccccccccccccccccaaacccccccccccccccccccaacjjjjqqqqqttwwwwwwwwwwwrrrooofffccccc | 
				
			|||
abcccccccccccccccccccccccccccccccccccccccccaaccccccccccaacccccccccccccccccccccccccaaacccccccccccccccccccccccccccccccccaaacccccccccccccccccaaaaaajjjjqqqqttwwwwwwsswwrrrrooofffccccc | 
				
			|||
abcccccaaaaccccccccccccccaacaaccccccccccccccccccccccccccccccccccccccccccccccccccccaacccccccccccccccccccccccccccccccaaaaaaaaccaaaacccccccccaaaaaacjjjiqqqtttwwwwsssssrrrrooofffccccc | 
				
			|||
abccccaaaaaccccccccccccccaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaaaccaaaaacccccccccaaaaacciiiiqqttswwwssssssrrroooogffccccc | 
				
			|||
abccccaaaaaacccccccccccccaaaaaacccaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaccaaaaaaccccccccaaaaacccciiiqqqssssssspppooooooogggaccccc | 
				
			|||
abccccaaaaaaccccccccaacccaaaaaaccccaacccccccccccccccccccccccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccaaaaaaccaaaaaaccccccccaaaaaccccciiiqqsssssspppppoooooggggaacccc | 
				
			|||
abccccaaaaaccccccaaaaacccaaaaaacaacaaaaaccccccccccccccccccccaacccccccaaaaacccccccccccaaaccccccccccccccccccccccccccccaaaaaacccaaaaacccccccccacccccccciiiqqqpssspppppgggggggggaaacccc | 
				
			|||
abccccccaaacccccccaaaaaccccaaaccaaaaaaaacccccccaacccccccaaccaacccccccaaaaaacccccccccaaaacccccccccccaaaaccccccccccccaaccaaacccaaacccccaaacaaaccccccccciiqqppppppphhhggggggggaaaacccc | 
				
			|||
abccccccccccccccccaaaaaccccccccccaaaaaccccccccaaacaaccccaaaaaacccccccaaaaaaaccccccccaaaacccccccccccaaaacccccccccaaaaaacccccccccccccccaaaaaaaccccccccciiippppppphhhhggggggcaaacccccc | 
				
			|||
abaacccccccccccccaaaaaccccccccccccaaaaaccccccccaaaaacccccaaaaaaacccccaaaaacaaacccccccaaacccccccccccaaaacccccccccaaaaacccccccccccccccccaaaaaacccccccccciiiippphhhhhhcccccccaaacccccc | 
				
			|||
abaacccccccccccccccaaacccccccccccaaacaaccccccaaaaaaccccccaaaaaaacccaaccaaacaaaaccaaaccccccccccccccccaaacccccccccaaaaaaacccccccccccccccaaaaaaaacccccccciiihhhhhhhhaaaccccccccccccccc | 
				
			|||
abaaccccccccccccccccccccccccccccccaacccccccccaaaaaaaacccaaaaaaccaaaaaacccccaaaacaaaaaccccccccccccccccccccccccccaaaaaaaaccccccccccccccaaaaaaaaaccccccccciihhhhhhcaaaacccccccccccccca | 
				
			|||
abaaccccccccccccccccccccccccccccccccaacccccccaacaaaaacccaaaaaaccaaaaacccccccaaaaaaaacccccccccccccccccccccccccccaaaaaaaacccccccccaaacaaaaaaaaaacccccccccccchhhaccccaacccccccccccccca | 
				
			|||
abaaccccccccccccccccccccccccccccccccaaaaaaccccccaaccccccccccaaccaaaaaaacccccaaaaaaaccccccccccccccccccccccccaaaccacaaacccccccccccaaaaaaacaaacaaaaaacccccccccaaacccccccccccccccaaaaaa | 
				
			|||
abccccccccccccccccccccccccccccccccccaaaaaccccccaaccccccccccccccaaaaaaaacaaaaaaaaaaccccccccccccccccccccccccaaaaaaccaaaccccccccccccaaaaaacaaacaaaaaacccccccccaaaccccccccccccccccaaaaa | 
				
			|||
abccccccccccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccaaaaaaaacaaaaaaaaaaaaacccccccccccccccccccccaaaaaacccccccccccccccaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccaaaaa | 
				
			|||
@ -0,0 +1,2 @@ | 
				
			|||
484 | 
				
			|||
478 | 
				
			|||
@ -1,13 +1,4 @@ | 
				
			|||
#!/bin/sh | 
				
			|||
rm img/*.gif | 
				
			|||
waitjobs() { | 
				
			|||
    while [ "$(jobs -p | wc -l)" -ge "$1" ]; do wait; done | 
				
			|||
} | 
				
			|||
for x in img/*.pam; do | 
				
			|||
    echo "$x" | 
				
			|||
    pamtogif -quiet "$x" > "$x.gif" & | 
				
			|||
    waitjobs "$(nproc)" | 
				
			|||
done | 
				
			|||
wait | 
				
			|||
gifsicle -d1 --verbose img/*.gif > anim.gif | 
				
			|||
ffmpeg -i anim.gif -filter:v "setpts=0.1*PTS,scale=iw*4:ih*4:flags=neighbor" -r 100 anim.webm | 
				
			|||
ffmpeg -threads 0 -pattern_type glob -i "img/*.pam" -r 60 \ | 
				
			|||
    -filter:v "setpts=0.05*PTS,scale=iw*4:ih*4:flags=neighbor" \ | 
				
			|||
    anim.webm | 
				
			|||
 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue