티스토리 뷰

728x90

문제 링크

https://www.acmicpc.net/problem/4828

 

4828번: XML

인터넷프로그래밍 교수 이다솜은 XML이야말로 세상을 바꿀 혁신적인 언어라고 믿으며, 항상 학생들에게 XML의 장점을 어필한다. 그러나 잘못 사용되었다가는 지구를 파괴할 수도 있는 무시무시

www.acmicpc.net

 

풀이

죽여..줘...

 

 

정답 코드

const fs = require('fs');
const stdin = fs.readFileSync('/dev/stdin').toString().split('\n');
const input = (() => {
    let line = 0;
    return () => stdin[line++];
})();

const main = function () {
    let s, ans = [];
    let n = stdin.length;
    const valid = () => ans.push(`valid\n`),
        invalid = () => ans.push(`invalid\n`);
    const inner = str => [Number(str[0] !== '<'), str.substr(1, str.length - 2)];
    const last = str => str[str.length - 1];

    const regex = /<{1}[0-9a-z]+>|<{1}\/[0-9a-z]+>|<{1}[0-9a-z]+\/>|&{1}x([0-9A-Fa-f][0-9A-Fa-f])+;|&lt;|&gt;|&amp;/g

    while (--n) {
        s = input();
        const asciiFlag = s.split('').reduce((flag, c) => {
            const ascii = c.charCodeAt(0);
            return flag && (32 <= ascii && ascii <= 127);
        }, true);

        if (!asciiFlag) {
            invalid();
            continue;
        }

        let plain = s.split(regex),
            rest = s.match(regex);

        if (plain) {
            const isValid = plain
                .filter(Boolean)
                .reduce((flag, str) => flag && (str.search(/[<>&]/) === -1), true);
            if (!isValid) {
                invalid();
                continue;
            }
        }
        if (rest) {
            const context = [];
            Object.assign(context, {
                empty() {
                    return this.length === 0;
                },
                back() {
                    return this[this.length - 1];
                },
            });

            let isValid = true;
            rest
                .filter(Boolean)
                .map(inner)
                .forEach(([type, str]) => {
                    if (type === 0) {
                        // tag
                        if (last(str) === '/') return;
                        if (str[0] !== '/') {
                            context.push(str);
                        } else {
                            if (context.empty() || context.back() !== str.substr(1)) {
                                isValid = false;
                                return;
                            }
                            context.pop();
                        }
                    } else {
                        if (str[0] !== 'x' && !['lt', 'gt', 'amp'].includes(str)) {
                            isValid = false;
                        }
                    }
                });
            if (!context.empty()) {
                isValid = false;
            }
            if (!isValid) {
                invalid();
                continue;
            }
        }

        valid();
    }

    console.log(ans.join(''));
};

main();
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함