Martin Ender๋ ์ต๊ทผ 100K๋ฅผ ๊ธฐ๋กํ์ผ๋ฉฐ ๊ฝค ๋ฉ์ง ์ธ์ด๋ฅผ ์๊ฐํด ๋์ต๋๋ค . ์ฐ๋ฆฌ๋ ๊ทธ๋ค ์ค ํ๋ ์ธ Hexagony (๊ทธ๋ฆฌ๊ณ Retina์ ๋ํ ์ฝ๊ฐ์ ์ ๊ท ํํ์ ) ์ ์ฝ๊ฐ์ ์ฌ๋ฏธ๋ฅผ ๊ฐ์ง ๊ฒ์ ๋๋ค.
๊ฐ๋จํ ๊ฐ์๋ก, Hexagony ๊ทธ๋ฆฌ๋ ๋ฅผ ์ ๋ ฅํ๊ณ ํด๋น ๊ทธ๋ฆฌ๋์ ํ ์คํธ ๋ฌธ์์ด๊ณผ ์ผ์นํ๋ ๊ฒฝ๋ก๊ฐ ์๋์ง ํ๋ณ ํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด์ผ ํฉ๋๋ค.
์์ฑ
Hexagony๋ ๋ค์ ๋จ๊ณ๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ ๋ฌธ์์ด์์ ์ก๊ฐํ์ ์์ฑํฉ๋๋ค.
- ์ต์ ์ก๊ฐํ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํ์ญ์์ค (๋์ ๊ธธ์ด๋ฅผ ์ทจํ๊ณ ๊ฐ์ฅ ๊ฐ๊น์ด 16 ์ง์๋ก ๋ฐ์ฌ๋ฆผํ์ญ์์ค )
- ์์ ํฌ๊ธฐ์ ์ก๊ฐํ์ผ๋ก ํ ์คํธ ๊ฐ์ธ๊ธฐ
- ๋ก ๋๋จธ์ง ์์น๋ฅผ ์ฑ ์๋๋ค
.
.
์๋ฅผ ๋ค์ด, ํ
์คํธ ๋ฌธ์์ด์ abcdefghijklm
์ธก๋ฉด ๊ธธ์ด 3์ ์ก๊ฐํ์ด ํ์ํ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด๋ฉ๋๋ค.
a b c
d e f g
h i j k l
m . . .
. . .
์ด์ 6 ๊ฐํ์ผ๋ก ์ฌํ ํ ์์๋ 6 ๊ฐ์ง ๋ฐฉํฅ์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ก๊ฐํ์์์์ e
์ธ์ ํฉ๋๋ค abfjid
.
์ธ์ฅ
๋ํ Hexagony์์๋ ์ก๊ฐํ์ด ๋ค์๊ณผ ๊ฐ์ด ๋ฉํ๋ฉ๋๋ค.
. . . . . a . . . . f . . a . .
a b c d e . . b . . . . g . . . b . . f
. . . . . . g . . c . . . . h . . a . c . . g .
. . . . . . . . h . . d . . . . u . . b . . d . . h . .
f g h i j k . i . . e . . j . . c . e . . i . .
. . . . . . j . . f k . . d . . . j . .
. . . . . k . . . . e . . k . .
๋ ๋ฒ์งธ์ ๋ค ๋ฒ์งธ ์๋ฅผ ๋ณด๋ฉด ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ํฌ์ฅ๋์ด ์์์๋ ๋ถ๊ตฌํ๊ณ ๊ฐ์ ์ง์ ์์๋ ๋ฐฉ๋ฒ a
๊ณผ k
์์น๋ฅผ ํ์ธํ์ญ์์ค. ์ด ์ฌ์ค๋ก ์ธํด์ด ์ง์ ๋ค์ 5 ๊ณณ์ ๋ค๋ฅธ ์์น์๋ง ์ธ์ ํด ์์ต๋๋ค .
์ด๊ฒ์ ๋ ๋ช ํํ๊ฒํ๋ ค๋ฉด :
a b c d
e f g h i
j k l m n o
p q r s t u v
w x y z A B
C D E F G
H I J K
- ๊ฐ์ฅ์๋ฆฌ๋ ๋ฐ๋์ชฝ ์ด์ (
b->I
๋ฐG->j
) ์ผ๋ก ์ค ๋ฐ๊ฟ๋ฉ๋๋ค . - ์ / ์๋ ๋ชจ์๋ฆฌ๋ ๋ฐ๋์ชฝ ๊ฐ์ด๋ฐ ๋ชจ์๋ฆฌ์ ์ / ์๋ (
d->K,p
๋ฐH->a,v
) ๋ก ๋๋ฌ์ธ ์ ๋๋ค. - ๊ฐ์ด๋ฐ ๋ชจ์๋ฆฌ๋ ์์ชฝ ๋ฐ ์๋์ชฝ ๋ชจ์๋ฆฌ ๋ชจ๋๋ก ์ค ๋ฐ๊ฟ (
v->a,H
)
๊ฒฝ๋ก
๋์ผํ ์์น๋ก ๋์ ๊ฐ์ง ์๊ณ ์ธ์ ํ ์์น์ ์ํ์ค๊ฐ ๋๋ ๊ฒฝ๋ก ์ ๋๋ค.
a b c
d e f g
h i f k l
m . . .
. . .
์์ ์ก๊ฐํ์์ aefkgm
์ ํจํ ๊ฒฝ๋ก์
๋๋ค. ๊ทธ๋ฌ๋, abfd
์ ํจํ ๊ฒฝ๋ก๊ฐ ์๋ ( f
์ d
์ธ์ ํ์ง ์์), ๋ฐ abea
์ ํจํ (๋ฐ๋ ๋ฆฌํด์๋ a
์์น).
์ด๋ฌํ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ฌ ํ
์คํธ์ ์ผ์น์ํฌ ์ ์์ต๋๋ค (์ : ์ ๊ท์) . ์์ซ์ ๋ฌธ์๋ ์์ ๊ณผ .
์ผ์นํ๋ฉฐ ๋ชจ๋ ๋ฌธ์์ ์ผ์นํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ฒฝ๋ก๊ฐ aej..lgm
์ผ์นํฉ๋๋ค aej..lgm
, aejAAlgm
, aeja.lgm
, ๋๋ aej^%gm
.
์ ์ถ๋ ฅ
ํ๋ก๊ทธ๋จ์ ์ด๋ค ์์๋ก๋ ๋ ๊ฐ์ ๋ฌธ์์ด์ ๊ฐ์ ธ์ผํฉ๋๋ค. ์ฒซ ๋ฒ์งธ ๋ฌธ์์ด์ ๋น์ด ์์ง ์์ผ๋ฉฐ ์์ซ์๋ก๋ง ๊ตฌ์ฑ๋ฉ๋๋ค [a-zA-Z0-9]
. ์๋์ค์ธ ์ก๊ฐํ์ ๋ํ๋
๋๋ค. ๋ ๋ฒ์งธ ๋ฌธ์์ด์ ์ธ์ ๊ฐ๋ฅํ ๋ฌธ์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
์ฃผ์ด์ง ํ ์คํธ ๋ฌธ์์ด๊ณผ ์ผ์นํ๋ ์ก๊ฐํ ๊ฒฝ๋ก๊ฐ ์์ผ๋ฉด ๊ฑฐ์ง ๊ฐ์ ๋ฐํํด์ผํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ฑฐ์ง ๊ฐ์ ๋๋ค.
ํ ์คํธ ์ฌ๋ก
์ง์คํ :
"a","a"
"ab","a"
"ab","b"
"ab","ba"
"ab","aba"
"ab","&"
"ab","#7.J!"
"ab","aaaaaa"
"ab","bgjneta"
"ab","cebtmaa"
"abcdefg","dfabcg"
"AbCDeFG","GCbAeFD"
"aaaabbb","aaababb"
"abcdefghijklmnopqrs","alq"
"abcdefghijklmnopqrs","aqnmiedh"
"abcdefghijklmnopqrs","adhcgkorbefjimnqlps"
"11122233344455","12341345123245"
"abcdefgh","h%a"
"abcdefghijklm","a)(@#.*b"
"abcdefghijklm","a)(@#.*i"
"abcdefghij","ja"
"abcdefghijklmno","kgfeia"
"abcdefghijklmno","mmmmmiea"
"abcdefghijklmno","mmmmmlae"
"abcdefghijklmno","ja"
"abcdefghijklmnopqrs","eijfbadhmnokgcsrql"
๊ฑฐ์ง :
"a","b"
"a","%"
"a","."
"a","aa"
"a","a."
"ab","#7.J!*"
"ab","aaaaaaa"
"ab","aaaabaaa"
"ab","123456"
"abcdefg","bfgedac"
"abcdefg","gecafdb"
"abcdefg","GCbaeFD"
"aaaabbb","aaaaabb"
"abcdefghijklmnopqrs","aqrcgf"
"abcdefghijklmnopqrs","adhlcgknbeifjm"
"abcdefghijklmnopqrs","ja"
"abcdefghijklm","a)(@#.*&"
"abcdefghijklmno","a)(@bfeijk"
"abcdefghijklmno","kgfeic"
"abcdefghijklmno","mmmmmmiea"
์ด๊ฒ์ ์ฝ๋ ๊ณจํ ์ด๋ฏ๋ก ์ ํธํ๋ ์ธ์ด๋ก ๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ๋ต๋ณํ์ญ์์ค.
๋ต๋ณ
๋ ํฐ ๋ 744 ๋ฐ์ดํธ
์ฃ์กํฉ๋๋ค. ์ด๋ฒ์๋ Hexagony๊ฐ ์์ต๋๋ค โฆ
๋ฐ์ดํธ ์๋ ISO 8859-1 ์ธ์ฝ๋ฉ์ ๊ฐ์ ํฉ๋๋ค.
.+ยถ
$.'$*_ยถ$&
^_ยถ
ยถ
((^_|\2_)*)_\1{5}_+
$2_
^_*
$.&$*ร_$&$&$.&$*ร
M!&m`(?<=(?=ร*(_)+)\A.*)(?<-1>.)+(?(1)!)|^.*$
O$`(_)|.(?=.*$)
$1
G-2`
T`d`ร-ร
m`\A(\D*)(?(_)\D*ยถ.|(.)\D*ยถ\2)((.)(?<=(?<4>_)\D+)?((?<=(?<1>\1.)\4\D*)|(?<=(?<1>\D*)\4(?<=\1)\D*)|(?<=\1(.(.)*ยถ\D*))((?<=(?<1>\D*)\4(?>(?<-7>.)*)ยถ.*\6)|(?<=(?<1>\D*)(?=\4)(?>(?<-7>.)+)ยถ.*\6))|(?<=(ร)*ยถ.*)((?<=(?<1>\1.(?>(?<-9>ยถ.*)*))^\4\D*)|(?<=(?<1>\D*)\4(?>(?<-9>ยถ.*)*)(?<=\1)^\D*)|(?<=(?<1>\1\b.*(?(9)!)(?<-9>ยถ.*)*)\4ร*ยถ\D*)|(?<=(?<1>\D*\b)\4.*(?(9)!)(?<-9>ยถ.*)*(?<=\1.)\b\D*))|(?<=(?<1>\1.(?>(?<-11>.)*)ยถ.*)\4(.)*ยถ\D*)|(?<=(?<1>\1(?>(?<-12>.)*)ยถ.*)\4(.)*ยถ\D*)|(?<=(?<1>\1.(?>(?<-13>.)*ยถ\D*))\4(\w)*\W+.+)|(?<=(?<1>.*)\4(?>(?<-14>.)*ยถ\D*)(?<=\1.)(\w)*\W+.+))(?<=\1(\D*).+)(?<!\1\15.*(?<-1>.)+))*\Z
์
๋ ฅ์ ์ฒซ ๋ฒ์งธ ํ์์ ๋์ ๋ฌธ์์ด์, ๋ ๋ฒ์งธ ํ์์ ์ก๊ฐํ์ ์์ํฉ๋๋ค. ์ธ์ 0
ํ๊ฑฐ๋ 1
๊ทธ์ ๋ฐ๋ผ.
์จ๋ผ์ธ์ผ๋ก ์ฌ์ฉํด๋ณด์ญ์์ค! ์ฒซ ๋ฒ์งธ ์ค์ ยฆ
์ค ๋ฐ๊ฟ ๋์ ๊ตฌ๋ถ ์ ์ํด ์ฌ์ฉํ๋ ๊ฐ ํ
์คํธ ์ค์ธ ํ
์คํธ ์ค์ํธ๋ฅผ ํ์ฑํํฉ๋๋ค .
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ ๋ฌผ๋ก ์ ๊ท์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๐ ๊ทธ๋ฆฌ๊ณ ์ด ๋์ ์ด ์ก๊ฐํ ์ ์ ๊ฐ ์ ์ฐจ์ ๊ด๋ จ์ด ์๋ค๋ ์ฌ์ค์ด ์๋๋ผ๋ฉด ์ด ๋๋ต์ ์ค์ ๋ก ~ 600 ๋ฐ์ดํธ ๊ธธ์ด์ ์ ๊ท ํํ์์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
์ด๊ฒ์ ์์ง ์ต์ ์ ๊ณจํ๋ ์๋์ง๋ง ๊ฒฐ๊ณผ์ ๋งค์ฐ ๋ง์กฑํฉ๋๋ค (์ด๋ฆ์ด ์ง์ ๋ ๊ทธ๋ฃน๊ณผ ์์์ ์ํด ํ์ํ ๋ค๋ฅธ ๊ฒ๋ค์ ์ ๊ฑฐํ ํ์ ์ฒซ ๋ฒ์งธ ์์
๋ฒ์ ์ ์ฝ 1000 ๋ฐ์ดํธ์์ต๋๋ค). ๋ฌธ์์ด๊ณผ ์ก๊ฐํ์ ์์๋ฅผ ๋ฐ๊ฟ์ผ๋ก์จ ์ฝ 10 ๋ฐ์ดํธ๋ฅผ ์ ์ฝ ํ ์ ์๋ค๊ณ ์๊ฐํ์ง๋ง ๋์ ์ ๊ท์์ ์์ ํ ๋ค์ ์์ฑํด์ผํฉ๋๋ค. ์ง๊ธ ๊ธฐ๋ถ์ด ์ข์ง ์์ต๋๋ค. G
์คํ
์ด์ง ๋ฅผ ์๋ตํ์ฌ 2 ๋ฐ์ดํธ๋ฅผ ์ ์ฝ ํ ์๋ ์์ง๋ง ์๋ฃจ์
์๋๋ฅผ ์๋นํ ๋๋ฆฌ๊ฒ ํ ์ ์์ผ๋ฏ๋ก ๊ณจํ๋ฅผ ํ ์์์๋ฟ๋ง ์๋๋ผ ๊ณจํ๋ฅผ ์น ๋๊น์ง ๋ณ๊ฒฝ์ ๊ธฐ๋ค๋ฆด ๊ฒ์
๋๋ค.
์ค๋ช
์ด ์๋ฃจ์ ์ ์ฃผ์ ๋ถ๋ถ์ ๋ฐธ๋ฐ์ฑ ๊ทธ๋ฃน์ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์ดํดํ๊ณ ์ถ๋ค๋ฉด ์ฝ์ด๋ณด์ญ์์ค. (๊ทธ๋ ์ง ์์ผ๋ฉด ๋น์ ์ ๋น๋ํ์ง ์์ ๊ฒ์ ๋๋ค.)
์๋ฃจ์ ์ ์ฒซ ๋ฒ์งธ ๋ถ๋ถ (์ฆ, ๋ง์ง๋ง ๋ ์ค์ ์ ์ธํ ๋ชจ๋ ๊ฒ)์ Hexagony ์์ค ์ฝ๋ ํ์ฅ์ ๋ํ ๋ด ๋๋ต์ ์์ ๋ ๋ฒ์ ์ ๋๋ค . ๋์ ๋ฌธ์์ด์ ๊ทธ๋๋ก ์ ์งํ๋ฉด์ ์ก๊ฐํ์ ๊ตฌ์ฑํ๊ณ ์ค์ ๋ก ๋์ ๋ฌธ์์ด ์์ ์ก๊ฐํ์ ๊ตฌ์ฑํฉ๋๋ค. ๋ฐ์ดํธ๋ฅผ ์ ์ฝํ๊ธฐ ์ํด ์ด์ ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ณ๊ฒฝํ์ต๋๋ค.
- ๋ฐฐ๊ฒฝ ๋ฌธ์๋
ร
๊ณต๋ฐฑ ๋์ ์ ๋ ฅ์ ์ ์ฌ์ ๊ณต๋ฐฑ๊ณผ ์ถฉ๋ํ์ง ์์ต๋๋ค. - no-op / wildcard ๋ฌธ์๋
_
๋์.
๊ทธ๋ฆฌ๋ ์ ์ ๋จ์ด ๋ฌธ์๋ก ํ์คํ๊ฒ ์๋ณ ํ ์ ์๋๋กํฉ๋๋ค. - ์ก๊ฐํ์ด ์ฒ์ ๊ตฌ์ฑ๋ ํ์ ๊ณต๋ฐฑ์ด๋ ๋ค์ฌ ์ฐ๊ธฐ๋ฅผ ์ฝ์ ํ์ง ์์ต๋๋ค. ๊ทธ๊ฒ์ ๊ฒฝ์ฌ ์ก๊ฐํ์ ์ ๊ณตํ์ง๋ง ์ค์ ๋ก ์์ ํ๊ธฐ๊ฐ ํจ์ฌ ํธ๋ฆฌํ๋ฉฐ ์ธ์ ๊ท์น์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
๋ค์์ ์์ ๋๋ค. ๋ค์ ํ ์คํธ ์ฌ๋ก์ ๊ฒฝ์ฐ :
ja
abcdefghij
์ฐ๋ฆฌ๋ ์ป๋๋ค :
รรabc
รdefg
hij__
____ร
___รร
ja
์ด๊ฒ์ ์ผ๋ฐ์ ์ธ ์ก๊ฐํ ๋ ์ด์์๊ณผ ๋น๊ตํ์ญ์์ค.
a b c
d e f g
h i j _ _
_ _ _ _
_ _ _
์ฐ๋ฆฌ๋ ์ด์์ด ์ด์ ๋ถ์์ชฝ๊ณผ ๋จ๋์ชฝ ์ด์์ ์ ์ธํ๊ณ ์ผ๋ฐ์ ์ธ 8 ๊ฐ์ ๋ฌด์ด ์ด์ ๋ชจ๋์์ ์ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ํ, ์์ง ๋ฐ ๋จ์ / ๋ถ๋ ์ธ์ ์ฑ์ ํ์ธํด์ผํฉ๋๋ค (์ ๊ฐ์ธ๋ ๊ฐ์ฅ์๋ฆฌ๊ฐ ์์ต๋๋ค). ์ด๋ณด๋ค ์์ ๋ ์ด์์์ ์ฌ์ฉ รร
ํ๋ฉด ํ์ํ ๋ ์ฆ์ ์ก๊ฐํ์ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ๊ธฐ ์ํด ๋์ ์๋ ๋ ์ด์์์ ์ฌ์ฉํ ์ ์๋ค๋ ๋ณด๋์ค ๊ฐ ์์ต๋๋ค.
์ด ํผ์ด ๊ตฌ์ฑ๋๋ฉด ์ ์ฒด ๋ฌธ์์ด์ ํ ๋ฒ ๋ ๋ณ๊ฒฝํฉ๋๋ค.
T`d`ร-ร
์ด๊ฒ์ ์ซ์๋ฅผ ํ์ฅ ASCII ๋ฌธ์๋ก ๋์ฒดํฉ๋๋ค
รรรรรร
รรรร
๊ทธ๊ฒ๋ค์ ์ก๊ฐํ๊ณผ ๋์ ๋ฌธ์์ด ๋ชจ๋์์ ๊ต์ฒด๋๊ธฐ ๋๋ฌธ์ ๋ฌธ์์ด์ ์ผ์น ์ฌ๋ถ์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค. ๋ํ, ๊ทธ๋ค์ ๋ฌธ์๋ถํฐ์
๋๋ค \w
๊ทธ๋ฆฌ๊ณ \b
์ฌ์ ํ ์ก๊ฐํ ์ธํฌ๋ก๋ฅผ ์๋ณํฉ๋๋ค. ์ด ๋์ฒด ์์
์ ์ด์ ์ ์ด์ \D
๋ค์ ์ ๊ท์์์ ๋ชจ๋ ๋ฌธ์ (ํนํ ์ค ๋ฐ๊ฟ ๋ฐ ๋น์ค ๋ฐ๊ฟ ๋ฌธ์) ๋ฅผ ์ผ์น์ํค๊ธฐ ์ํด ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ ์
๋๋ค. ์ฌ๋ฌ ์์น์์ ์ค ๋ฐ๊ฟ๋์ง ์์ ๋ฌธ์๋ฅผ ์ผ์น s
์์ผ์ผ .
ํ๊ธฐ ๋๋ฌธ์์ด ์ต์
์ ์ฌ์ฉํ ์ ์์ต๋๋ค .
์ด์ ๋ง์ง๋ง ๋นํธ : ๊ฒฝ๋ก๊ฐ ์ฃผ์ด์ง ๋ฌธ์์ด๊ณผ ์ผ์นํ๋์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ์ด๊ฒ์ ๋จ์ผ ๊ดด๋ฌผ ์ ๊ท์์ผ๋ก ์ํ๋ฉ๋๋ค. ์ ๊ทธ๋ฐ์ง ๋ฌผ์ด๋ด๋ ๋ ๊น์?!?! ๊ธ์, ์ด๊ฒ์ ๊ทผ๋ณธ์ ์ผ๋ก ์ญ ์ถ์ ๋ฌธ์ ์ ๋๋ค. ์ด๋๊ฐ์์ ์์ํ์ฌ ๋ฌธ์์ด๊ณผ ์ผ์นํ๋ ํ ๊ฒฝ๋ก๋ฅผ ์๋ํ๊ณ ์ผ๋จ ๊ฒฝ๋ก๋ฅผ ์ถ์ ํ์ง ์์ผ๋ฉด ๋ง์ง๋ง์ผ๋ก ์๋ ํ ๋ง์ง๋ง ๋ฌธ์์ ๋ค๋ฅธ ์ด์์ ์๋ํ์ญ์์ค. ํ ๊ฐ์ง์ ๊ท์์ผ๋ก ์์ ํ ๋ ๋ฌด๋ฃ๋ก ์ป๋ ๊ฒ์ ์ญ ์ถ์ ์ ๋๋ค. ๊ทธ๊ฒ์ ๋ฌธ์ ๊ทธ๋๋ก ์ ๊ท์ ์์ง์ดํ๋ ์ ์ผํ ์ผ์ ๋๋ค. ๋ฐ๋ผ์ ์ ํจํ ๊ฒฝ๋ก๋ฅผ ์ค๋ช ํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์ผ๋ฉด (์ด๋ฌํ ์ข ๋ฅ์ ๋ฌธ์ ์๋ ์ถฉ๋ถํ ๊น๋ค ๋กญ์ง ๋ง ๊ทธ๋ฃน ๋ฐธ๋ฐ์ฑ์ผ๋ก ๊ฐ๋ฅํ ์ ์์ต๋๋ค) ์ ๊ท์ ์์ง์ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ๋ก ์ค์์ ํด๋น ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๊ฒ์ ๋ถ๋ฅํฉ๋๋ค. ์ฌ๋ฌ ๋จ๊ณ๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ๊ฒ์์ ๊ตฌํํ๋ ๊ฒ์ด ๊ฐ๋ฅํ ๊ฒ์ ๋๋ค ( ๊ณผ๊ฑฐ์๋ ๊ทธ๋ ๊ฒ ํ์ ).์ด ํน๋ณํ ๊ฒฝ์ฐ์๋ ๋ ์งง์ ๊ฒ์ ๋๋ค.
์ ๊ท์์ผ๋ก ์ด๊ฒ์ ๊ตฌํํ ๋์ ํ ๊ฐ์ง ๋ฌธ์ ๋ ์ญ ์ถ์ ์ค์ ๊ฒฝ๋ก๋ฅผ ํตํด ์ ๊ท์ ์์ง์ ์ปค์๋ฅผ ์์๋ก ์๋ค๋ก ์์ง์ผ ์ ์๋ค๋ ๊ฒ์ ๋๋ค (๊ฒฝ๋ก๊ฐ ์ฌ๋ผ๊ฐ๊ฑฐ๋ ๋ด๋ ค๊ฐ ์ ์๊ธฐ ๋๋ฌธ์ ํ์ํฉ๋๋ค). ๋์ ์บก์ฒ ๊ทธ๋ฃน์์ ์์ฒด โ์ปค์โ๋ฅผ ์ถ์ ํ๊ณ ๋ชจ๋ ๋จ๊ณ์์ ์ ๋ฐ์ดํธํฉ๋๋ค (์ผ์์ ์ผ๋ก ์ปค์ ์์น๋ก ์ผ์์ ์ผ๋ก ์ด๋ํ ์ ์์). ๋ํ ์ด์ ์ ํ์ฌ ์์น๋ฅผ ๋ฐฉ๋ฌธํ์ง ์์๋์ง ํ์ธํ๋ ๋ฐ ์ฌ์ฉํ ๋ชจ๋ ๊ณผ๊ฑฐ ์์น๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
์ด์ ์์ํ๊ฒ ์ต๋๋ค. ๋ค์์ ์ด๋ฆ์ด ์ง์ ๋ ๊ทธ๋ฃน, ๋ค์ฌ ์ฐ๊ธฐ, ์ด์์ ๋ฌด์์ ์์๊ฐ ์ ๊ณ ์ผ๋ถ ์ฃผ์์ด์๋ ์ฝ๊ฐ ๋ ์ ์ ๋ฒ์ ์ ์ ๊ท ํํ์์ ๋๋ค.
\A
# Store initial cursor position in <pos>
(?<pos>\D*)
(?(_)
# If we start on a wildcard, just skip to the first character of the target.
\D*ยถ.
|
# Otherwise, make sure that the target starts with this character.
(?<first>.)\D*ยถ\k<first>
)
(?:
# Match 0 or more subsequent characters by moving the cursor along the path.
# First, we store the character to be matched in <next>.
(?<next>.)
# Now we optionally push an underscore on top (if one exists in the string).
# Depending on whether this done or not (both of which are attempted by
# the engine's backtracking), either the exact character, or an underscore
# will respond to the match. So when we now use the backreference \k<next>
# further down, it will automatically handle wildcards correctly.
(?<=(?<next>_)\D+)?
# This alternation now simply covers all 6 possible neighbours as well as
# all 6 possible wrapped edges.
# Each option needs to go into a separate lookbehind, because otherwise
# the engine would not backtrack through all possible neighbours once it
# has found a valid one (lookarounds are atomic).
# In any case, if the new character is found in the given direction, <pos>
# will have been updated with the new cursor position.
(?:
# Try moving east.
(?<=(?<pos>\k<pos>.)\k<next>\D*)
|
# Try moving west.
(?<=(?<pos>\D*)\k<next>(?<=\k<pos>)\D*)
|
# Store the horizontal position of the cursor in <x> and remember where
# it is (because we'll need this for the next two options).
(?<=\k<pos>(?<skip>.(?<x>.)*ยถ\D*))
(?:
# Try moving north.
(?<=(?<pos>\D*)\k<next>(?>(?<-x>.)*)ยถ.*\k<skip>)
|
# Try moving north-east.
(?<=(?<pos>\D*)(?=\k<next>)(?>(?<-x>.)+)ยถ.*\k<skip>)
)
|
# Try moving south.
(?<=(?<pos>\k<pos>.(?>(?<-x>.)*)ยถ.*)\k<next>(?<x>.)*ยถ\D*)
|
# Try moving south-east.
(?<=(?<pos>\k<pos>(?>(?<-x>.)*)ยถ.*)\k<next>(?<x>.)*ยถ\D*)
|
# Store the number of 'ร' at the end in <w>, which is one less than the
# the side-length of the hexagon. This happens to be the number of lines
# we need to skip when wrapping around certain edges.
(?<=(?<w>ร)*ยถ.*)
(?:
# Try wrapping around the east edge.
(?<=(?<pos>\k<pos>.(?>(?<-w>ยถ.*)*))^\k<next>\D*)
|
# Try wrapping around the west edge.
(?<=(?<pos>\D*)\k<next>(?>(?<-w>ยถ.*)*)(?<=\k<pos>)^\D*)
|
# Try wrapping around the south-east edge.
(?<=(?<pos>\k<pos>\b.*(?(w)!)(?<-w>ยถ.*)*)\k<next>ร*ยถ\D*)
|
# Try wrapping around the north-west edge.
(?<=(?<pos>\D*\b)\k<next>.*(?(w)!)(?<-w>ยถ.*)*(?<=\k<pos>.)\b\D*)
)
|
# Try wrapping around the south edge.
(?<=(?<pos>\k<pos>.(?>(?<-x>.)*ยถ\D*))\k<next>(?<x>\w)*\W+.+)
|
# Try wrapping around the north edge.
(?<=(?<pos>.*)\k<next>(?>(?<-x>.)*ยถ\D*)(?<=\k<pos>.)(?<x>\w)*\W+.+)
)
# Copy the current cursor position into <current>.
(?<=\k<pos>(?<current>\D*).+)
# Make sure that no matter how many strings we pop from our stack of previous
# cursor positions, none are equal to the current one (to ensure that we use
# each cell at most once).
(?<!\k<pos>\k<current>.*(?<-pos>.)+)
)*
# Finally make sure that we've reached the end of the string, so that we've
# successfully matched all characters in the target string.
\Z
๋๋ ์ผ๋ฐ์ ์ธ ์์ด๋์ด๊ฐ ์ด๊ฒ์ผ๋ก๋ถํฐ ๋๋ต ๋ช ํํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ์์ง์ด๋ ๋์ ์ค ํ๋์ ์๋ ๋ฐฉ์์ ๋ํ ์๋ฅผ ๋ค์ด ์ปค์๋ฅผ ๋จ์ชฝ์ผ๋ก ์์ง์ด๋ ๋นํธ๋ฅผ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
(?<=(?<pos>\k<pos>.(?>(?<-x>.)*)ยถ.*)\k<next>(?<x>.)*ยถ\D*)
lookbehinds๋ ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก (๋๋ ์์์ ์๋๋ก) ์ฝ์ด์ผํฉ๋๋ค. ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
(?<=
(?<pos>
\k<pos> # Check that this is the old cursor position.
. # Match the character directly on top of the new one.
(?>(?<-x>.)*) # Match the same amount of characters as before.
ยถ.* # Skip to the next line (the line, the old cursor is on).
) # We will store everything left of here as the new
# cursor position.
\k<next> # ...up to a match of our current target character.
(?<x>.)* # Count how many characters there are...
ยถ\D* # Skip to the end of some line (this will be the line below
# the current cursor, which the regex engine's backtracking
# will determine for us).
)
\k<pos>
์ค์ ๋ก ๋ฌธ์์ด์ ์์ ๋ถ๋ถ์ ๋๋ฌํ๋๋ก ์ต์ปค๋ฅผ ์์ ๋ฐฐ์น ํ ํ์๋ ์์ต๋๋ค . <pos>
ํญ์ ร
๋ค๋ฅธ ๊ณณ์์๋ ์ฐพ์ ์์๋ ์์ผ๋ก ์์ ํ๋ฏ๋ก ์ด๋ฏธ ์์ ์ ์ต์ปค ์ญํ ์ํฉ๋๋ค.
์ด ๊ฒ์๋ฌผ์ ํ์ ์ด์์ผ๋ก ๋๋ฆฌ๊ณ ์ถ์ง ์์ผ๋ฏ๋ก ๋ค๋ฅธ 11 ๊ฐ์ง ์ฌ๋ก์ ๋ํด์๋ ์์ธํ ์ค๋ช
ํ์ง ์์ง๋ง ์์น์ ์ผ๋ก ๋ชจ๋ ๋น์ทํ๊ฒ ์๋ํฉ๋๋ค. <next>
๋ฐธ๋ฐ์ฑ ๊ทธ๋ฃน์ ์ฌ์ฉํ์ฌ ์ด์ ์ปค์ ์์น์์ ํน์ (ํ์ฉ ๊ฐ๋ฅํ) ๋ฐฉํฅ์ผ๋ก ์ฐพ์ ์ ์๋์ง ํ์ธํ ๋ค์ ์ผ์นํ๋ ๋ฌธ์์ด์์์ ์ ์ปค์ ์์น๋ก ์ ์ฅ <pos>
ํฉ๋๋ค.
๋ต๋ณ
ํ์ด์ฌ 3, 990 943 770 709 ๋ฐ์ดํธ
์ฒซ ๋ฒ์งธ ๋๋ต์ ๋๋ค.
ํธ์ง : ๊ณจํ ์ธ์ ๋ชฉ๋ก ๋ง๋ค๊ธฐ. ๋๋ ์ด์ ์ฝ๊ฐ ๋ค๋ฅธ ๊ณต์์ ์ฌ์ฉํฉ๋๋ค
ํธ์ง 2 : ๋ถํ์ํ ๋ณดํ์ ์ ๊ฑฐํ๊ณ ํจ์ฌ ๋ ๊ณจํ๋ฅผ ์ณค๋ค.
ํธ์ง 3 : ๋ชฉ๋ก์ ์์ธ์์ ์ขํ๋ก ๋ณํํ๊ธฐ์ํ ์ฝ๋๊ฐ ๋จ์ถ๋์ด ๋ช ๊ฐ์ง ์ฌํญ์ด ์ถ๊ฐ๋์์ต๋๋ค.
๋ฐ์ดํธ์ ๋๋ถ๋ถ์ ์ธ์ ๋ชฉ๋ก์ ๋ง๋๋ ๊ฒ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค (๊ณจํ ๊ฐ๋ฅ์ฑ์ด ๊ฐ์ฅ ๋์ต๋๋ค). ๊ทธ๋๋ถํฐ๋ ์๋ฃจ์ ์ ๊ฐ์ ๋ก ์ฒ๋ฆฌํ๋ ๊ฐ๋จํ ๋ฌธ์ ์ ๋๋ค (๋ ์ ์ ๋ฐ์ดํธ๋ก ์ํ ํ ์ ์์).
๊ณจํ :
from math import*
b=abs
c=max
e=range
f=len
A=input()
B=input()
C=ceil(sqrt((f(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-f(A))
G=[set()for x in e(D)]
I=lambda H:sum(E+.5-b(t-F+.5)for t in e(int(H+F)))
for x in e(D):
r=sum([[J-F]*(E-b(J-F))for J in e(E)],[])[x];q=x-I(r);s=-q-r;a=lambda q,r:G[x].add(int(q+I(r)));m=c(map(b,[q,r,s]))
if m==F:
if q in(m,-m):a(-q,-s)
if r in(m,-m):a(-s,-r)
if s in(m,-m):a(-r,-q)
for K,L in zip([1,0,-1,-1,0,1],[0,1,1,0,-1,-1]):
M,H=q+K,r+L
if c(map(b,[M,H,-M-H]))<C:a(M,H)
def N(i,O,P):
Q=O and O[0]==A[i]or'.'==A[i];R=0
if(2>f(O))*Q:R=1
elif Q:R=c([(x not in P)*N(x,O[1:],P+[i])for x in G[i]]+[0])
return R
print(c([N(x,B,[])for x in e(D)])*(f(B)<=D))
Ungolfed w / ์ค๋ช :
from math import*
#Rundown of the formula:
# * Get data about the size of the hexagon
# * Create lookup tables for index <-> coordinate conversion
# * q=0, r=0 is the center of the hexagon
# * I chose to measure in a mix of cubic and axial coordinates,
# as that allows for easy oob checks and easy retrevial
# * Create the adjacency list using the lookup tables, while
# checking for wrapping
# * Brute-force check if a path in the hexagon matches the
# expression
# shorten functions used a lot
b=abs
c=max
e=range
# Get input
prog=input()
expr=input()
# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later
sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1
# Pad prog with dots
prog+='.'*(hxln-len(prog))
# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row
nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln
# 4 5
# \ /
# 3 -- -- 0
# / \
# 2 1
# dirs contains the q,r and s values needed to move a point
# in the direction refrenced by the index
qdir=[1,0,-1,-1,0,1]
rdir=[0,1,1,0,-1,-1]
# generate nmbf using a summation formula I made
for r in e(nmrw-1):
nmbf[r+1]=int(nmbf[r]+nmrw+.5-b(r-sdln+1.5))
# generate in2q and in2r using more formulas
# cntr = running counter
cntr=0
for r in e(nmrw):
bgnq=c(-r,1-sdln)
for q in e(nmrw-b(r-sdln+1)):
in2q[cntr]=bgnq+q
in2r[cntr]=r-usdl
cntr+=1
# adjn = Adjacency sets
adjn=[set()for x in e(hxln)]
# Generate adjacency sets
for x in e(hxln):
#Get the q,r,s coords
q,r=in2q[x],in2r[x]
s=-q-r
# a = function to add q,r to the adjacency list
a=lambda q,r:adjn[x].add(q+nmbf[r+usdl])
# m = absolute value distance away from the center
m=c(map(b,[q,r,s]))
# if we are on the edge (includes corners)...
if m==usdl:
# add the only other point it wraps to
if q in(m,-m):
a(-q,-s)
if r in(m,-m):
a(-s,-r)
if s in(m,-m):
a(-r,-q)
# for all the directions...
for d in e(6):
# tmp{q,r,s} = moving in direction d from q,r,s
tmpq,tmpr=q+qdir[d],r+rdir[d]
# if the point we moved to is in bounds...
if c(map(b,[tmpq,tmpr,-tmpq-tmpr]))<sdln:
# add it
a(tmpq,tmpr)
# Recursive path checking function
def mtch(i,mtst,past):
# dmch = Does the place we are on in the hexagon match
# the place we are in the expression?
# out = the value to return
dmch=mtst and mtst[0]==prog[i]or'.'==prog[i]
out=0
# if we are at the end, and it matches...
if(2>len(mtst))*dmch:
out=1
# otherwise...
elif dmch:
# Recur in all directions that we haven't visited yet
# replace '*' with 'and' to speed up the recursion
out=c([(x not in past)*mtch(x,mtst[1:],past+[i])for x in adjn[i]]+[0])
return out
# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(c([mtch(x,expr,[])for x in e(hxln)])*(len(expr)<=hxln))
๋ ํฐ ๋์ ๋๋ฌด ๊ฐ๊น์ด! ๐ ์, ๋ ํฐ ๋๋ฅผ ์ด๊ฒผ๋ค!
๋ต๋ณ
์๋ฐ ์คํฌ๋ฆฝํธ (ES6), 511 500 496 ๋ฐ์ดํธ
(H,N)=>{C=(x,y)=>(c[x]=c[x]||[])[y]=y;S=d=>(C(x,y=x+d),C(y,x),C(s-x,s-y),C(s-y,s-x));r=(x,p,v)=>{p<N.length?(v[x]=1,c[x].map(n=>!v[n]&&(H[n]==N[p]||H[n]=='.')&&r(n,p+1,v.slice()))):K=1};for(e=x=K=0;(s=3*e*++e)<(l=H.length)-1;);H+='.'.repeat(s+1-l);for(a=[],b=[],c=[[]],w=e;w<e*2;){a[w-e]=x;b[e*2-w-1]=s-x;for(p=w;p--;x++){w-e||S(s-e+1);w<e*2-1&&(S(w),S(w+1));p&&S(1)}a[w]=x-1;b[e*3-++w]=s-x+1}a.map((v,i)=>S(b[i]-(x=v)));[N[0],'.'].map(y=>{for(x=-1;(x=H.indexOf(y,x+1))>-1;r(x,1,[]));});return K}
์ธ ๊ณจํ ๋ฐ ๋๊ธ
// Entry point
// H = haystack (the string the hexagon is filled with)
// N = needle (the substring we're looking for)
(H, N) => {
// C(x, y) - Helper function to save a connection between two locations.
// x = source location
// y = target location
C = (x, y) => (c[x] = c[x] || [])[y] = y;
// S(d) - Helper function to save reciprocal connections between two locations
// and their symmetric counterparts.
// d = distance between source location (x) and target location
S = d => (C(x, y = x + d), C(y, x), C(s - x, s - y), C(s - y, s - x));
// r(x, p, v) - Recursive path search.
// x = current location in hexagon
// p = current position in needle
// v = array of visited locations
r = (x, p, v) => {
p < N.length ?
(v[x] = 1, c[x].map(n => !v[n] && (H[n] == N[p] || H[n] == '.') &&
r(n, p + 1, v.slice())))
:
K = 1
};
// Compute e = the minimum required edge width of the hexagon to store the haystack.
// Also initialize:
// x = current location in hexagon
// l = length of haystack
// s = size of hexagon (number of locations - 1)
// K = fail/success flag
for(e = x = K = 0; (s = 3 * e * ++e) < (l = H.length) - 1;);
// Pad haystack with '.'
H += '.'.repeat(s + 1 - l);
// Build connections c[] between locations, using:
// x = current location
// w = width of current row
// p = position in current row
// Also initialize:
// a[] = list of locations on top left and top right edges
// b[] = list of locations on bottom left and bottom right edges
for(a = [], b = [], c = [[]], w = e; w < e * 2;) {
a[w - e] = x;
b[e * 2 - w - 1] = s - x;
for(p = w; p--; x++) {
// connection between top and bottom edges
w - e || S(s - e + 1);
// connections between current location and locations below it
w < e * 2 - 1 && (S(w), S(w + 1));
// connection between current location and next location
p && S(1)
}
a[w] = x - 1;
b[e * 3 - ++w] = s - x + 1
}
// Save connections between top left/right edges and bottom left/right edges.
a.map((v, i) => S(b[i] - (x = v)));
// Look for either the first character of the needle or a '.' in the haystack,
// and use it as the starting point for the recursive search. All candidate
// locations are tried out.
[N[0], '.'].map(y => {
for(x = -1; (x = H.indexOf(y, x + 1)) > -1; r(x, 1, []));
});
// Return fail/success flag.
return K
}
ํ ์คํธ ์ฌ๋ก
์๋ ์ค ๋ํซ์ ๋ชจ๋ ์ง์ค๋๊ณ ํ์ ํ ์คํธ ์ฌ๋ก๋ฅผ ์๋ดํฉ๋๋ค.
let f =
(H,N)=>{C=(x,y)=>(c[x]=c[x]||[])[y]=y;S=d=>(C(x,y=x+d),C(y,x),C(s-x,s-y),C(s-y,s-x));r=(x,p,v)=>{p<N.length?(v[x]=1,c[x].map(n=>!v[n]&&(H[n]==N[p]||H[n]=='.')&&r(n,p+1,v.slice()))):K=1};for(e=x=K=0;(s=3*e*++e)<(l=H.length)-1;);H+='.'.repeat(s+1-l);for(a=[],b=[],c=[[]],w=e;w<e*2;){a[w-e]=x;b[e*2-w-1]=s-x;for(p=w;p--;x++){w-e||S(s-e+1);w<e*2-1&&(S(w),S(w+1));p&&S(1)}a[w]=x-1;b[e*3-++w]=s-x+1}a.map((v,i)=>S(b[i]-(x=v)));[N[0],'.'].map(y=>{for(x=-1;(x=H.indexOf(y,x+1))>-1;r(x,1,[]));});return K}
let truthy = [
["a","a"],
["ab","a"],
["ab","b"],
["ab","ba"],
["ab","aba"],
["ab","&"],
["ab","#7.J!"],
["ab","aaaaaa"],
["ab","bgjneta"],
["ab","cebtmaa"],
["abcdefg","dfabcg"],
["AbCDeFG","GCbAeFD"],
["aaaabbb","aaababb"],
["abcdefghijklmnopqrs","alq"],
["abcdefghijklmnopqrs","aqnmiedh"],
["abcdefghijklmnopqrs","adhcgkorbefjimnqlps"],
["11122233344455","12341345123245"],
["abcdefgh","h%a"],
["abcdefghijklm","a)(@#.*b"],
["abcdefghijklm","a)(@#.*i"],
["abcdefghij","ja"],
["abcdefghijklmno","kgfeia"],
["abcdefghijklmno","mmmmmiea"],
["abcdefghijklmno","mmmmmlae"],
["abcdefghijklmno","ja"],
["abcdefghijklmnopqrs","eijfbadhmnokgcsrql"]
];
let falsy = [
["a","b"],
["a","%"],
["a","."],
["a","aa"],
["a","a."],
["ab","#7.J!*"],
["ab","aaaaaaa"],
["ab","aaaabaaa"],
["ab","123456"],
["abcdefg","bfgedac"],
["abcdefg","gecafdb"],
["abcdefg","GCbaeFD"],
["aaaabbb","aaaaabb"],
["abcdefghijklmnopqrs","aqrcgf"],
["abcdefghijklmnopqrs","adhlcgknbeifjm"],
["abcdefghijklmnopqrs","ja"],
["abcdefghijklm","a)(@#.*&"],
["abcdefghijklmno","a)(@bfeijk"],
["abcdefghijklmno","kgfeic"],
["abcdefghijklmno","mmmmmmiea"]
];
console.log(
'Testing truthy test cases:',
truthy.every(v => f(v[0], v[1])) ? 'passed' : 'failed'
);
console.log(
'Testing falsy test cases:',
falsy.every(v => !f(v[0], v[1])) ? 'passed' : 'failed'
);