Jelly 인코딩 309 바이트
“Æ÷“¥s“ɲ“¡µ’;“ịƊ⁴çNṂ‘_\
OḌ;¢*5$%¥/µ“+⁷ż!¤ña¡jIȧƁfvḶg/Ọ=^ƝĠ0Ẇƭ³½N~=.Ɗ°ɗẇ⁵\ɦ*ɠPf⁾?ṾHḣ 2=⁹ƒ!©ƊĠṣƥ®Ƙ0Yƙ>!ȧtƊN0w,$ɠẎ46fẋ⁷(ṣẆm⁾ŻƓṫµsçwṣḂḲd0Ruṛ’ḃ21+\iµØW“&;:' ”;“¡3ȧ%⁾xƑ?{Ñṃ;Ċ70|#%ṭdṃḃ÷ƑĠẏþḢ÷ݳȦṖcẇọqƁe ʠ°oḲVḲ²ụċmvP[ỴẊẋ€kṢ ȯḂ;jɓỴẏeṾ⁴ḳḢ7Ẓ9ġƤṙb€xÇ4ɗ⁻>Ẉm!Ƈ)%Ḃẇ$ġ£7ȧ`ỵẈƘɗ¡Ṃ&|ƙƥ³ẏrṛbḋƙċ⁻ṁƲRṀẹṾ<ñ⁻Ṅ7j^ɓĊ’b58¤ị;0ị@
ḲÇ€t0”@;Ṫ
온라인으로 사용해보십시오!
나는 내 자신의 도전에 갈 시간이었다 결정했다. Jelly (및 8 비트 코드 페이지)를 사용하면 ASCII 전용 언어에 비해 12.5 %의 이점이 있으며 Jelly는 이름이 짧은 기본 변환 연산자가 내장되어 있기 때문에 이러한 문제에 편리하지만 대부분의 비용을 절약 할 수 있습니다. 압축 알고리즘이 향상 되었기 때문입니다 (이 프로그램의 평균 괴물 유형 당 1 바이트 미만).
알고리즘 및 설명
단어 기반 분류
좋은 점수를 얻으려면 다른 항목보다 입력의 구조를 더 잘 사용해야한다고 결정했습니다. 눈에 띄는 것 중 하나는 많은 몬스터들이 " 형용사 종 " 이라는 형식의 이름을 가지고 있다는 것입니다 . a red dragon
와 a blue dragon
는 둘 다 용의 유형이므로로 나타납니다 D
. 일부 다른 몬스터는 " 종 직업 "과 같은 이름을 가지고 있습니다 orc shaman
; 오크의 유형으로, 이것은로 나타납니다 o
. 복잡한 문제는 언데드입니다. a kobold zombie
는 kobold 와 zombie이며 후자의 상태는 NetHack 괴물 명명에서 우선하므로이를 다음과 같이 분류하려고합니다 Z
.
따라서 몬스터 이름에 나오는 단어를 다음과 같이 분류했습니다. 표시기 는 적절한 몬스터 클래스를 강력하게 제안하는 단어입니다 (예 : 몬스터가 클래스에 sphere
있음을 강력하게 제안합니다 e
). 모호한 단어가 훨씬 덜 제안의 만드는 단어입니다 ( lord
많이 얘기하지 않습니다), 그리고 다른 모든 단어는 nonwords 우리는 신경 쓰지 않는다. 기본 아이디어는 괴물 이름의 단어를 끝에서 뒤로 시작하여 첫 번째 표시자를 선택한다는 것입니다. 따라서 각 몬스터 이름에는 적어도 하나의 표시기가 포함되어 있어야하며, 그 뒤에 완전히 모호한 단어가옵니다. 예외적으로, 괴물의 이름에 나타나는 단어는@
(가장 큰 그룹)은 모두 모호한 것으로 분류됩니다. 표시기 앞에 무엇이든지 나타날 수 있습니다. 예를 들어, 색상 이름 (예 red
:)은 항상 표시기보다 이름 앞에 먼저 표시되므로 단어가 아닌 것으로 간주됩니다 (몬스터의 신원을 확인하는 동안 절대 검사되지 않기 때문에).
결국이 프로그램은 다른 프로그램과 마찬가지로 해시 테이블로 내려갑니다. 그러나 표에는 모든 몬스터 이름 또는 몬스터 이름으로 나타나는 모든 단어에 대한 항목이 포함되어 있지 않습니다. 오히려 표시기 만 포함합니다. 모호한 단어의 해시는 표에 나타나지 않지만 빈 슬롯에 할당되어야합니다 (모호한 단어를 찾으려고 시도하면 항상 비어 있음). 비 단어의 경우, 비 단어를 찾는 값을 절대 사용하지 않기 때문에 표에 단어가 표시되는지 또는 해시가 충돌하는지 여부는 중요하지 않습니다. (표가 상당히 희박하므로 대부분의 비 단어가 표에 나타나지 않지만 flesh
해시 충돌의 결과로 표에서 와 같은 몇 개가 발견됩니다.)
다음은 프로그램의이 부분이 어떻게 작동하는지에 대한 몇 가지 예입니다.
woodchuck
은 한 단어 길이이므로 (따라서 표시기), 테이블 조회 woodchuck
는 의도 된 대답 을 제공합니다 r
.
abbot
또한 한 단어로되어 있지만처럼 보입니다 @
. 따라서 abbot
모호한 단어로 간주됩니다. 테이블 조회가 비어 있고 @
기본적으로 답변을 반환합니다 .
vampire lord
표시기 (에 vampire
해당 V
)와 모호한 단어 ( lord
표에없는)로 구성됩니다. 즉, 두 단어를 모두 (역순으로) 확인한 다음에 정답을 제공합니다 V
.
gelatinous cube
비 단어 ( gelatinous
, H
해시 충돌 로 인한) 및 표시기 ( cube
, 해당 b
)로 구성됩니다. 표에서 찾은 마지막 단어 만 가져 오면 b
예상대로를 반환합니다 .
gnome mummy
두 지표 구성 gnome
에 대응 G
하고 mummy
대응 M
. 우리는 마지막 지표를 가져 와서 M
원하는 것을 얻습니다 .
단어 기반 분류를 처리하는 코드는 Jelly 프로그램의 마지막 줄입니다. 작동 방식은 다음과 같습니다.
ḲÇ€t0”@;Ṫ
Ḳ Split on spaces
Ç€ Call function 2 (table lookup) on each entry
t0 Remove trailing zeroes (function 2 returns 0 to mean "not found")
”@; Prepend an @ character
Ṫ Take the last result
두 가지 실제 사례가 있습니다. 입력이 전체적으로 모호한 단어로 구성된 경우 t0
테이블 조회의 전체 출력을 삭제하고 @
기본적으로 결과를 얻습니다 . 입력에 표시기가있는 경우 t0
가장 오른쪽 표시기의 오른쪽에있는 항목을 삭제 Ṫ
하고 해당 표시기에 대한 해당 결과를 제공합니다.
테이블 압축
물론 입력을 단어로 나누는 것만으로는 문제가 해결되지 않습니다. 우리는 여전히 지표와 해당 몬스터 클래스 간의 대응 관계 (그리고 모호한 단어의 대응 부족)를 인코딩해야합니다. 이를 위해 사용 된 181 개의 항목 (181 개의 지표에 해당; 378 개의 몬스터에 비해 크게 개선되었습니다!)과 966 개의 총 항목 (해시 함수의 966 출력 값에 해당)으로 스파 스 테이블을 구성했습니다. 테이블은 두 개의 문자열을 사용하여 프로그램에서 인코딩됩니다. 첫 번째 문자열은 테이블에서 "갭"의 크기를 지정합니다 (항목이 없음). 두 번째 문자열은 각 항목에 해당하는 몬스터 클래스를 지정합니다. 이것들은 기본 변환을 통해 간결하게 표현됩니다.
Jelly 프로그램에서 테이블 조회 코드는 프로그램 자체와 함께 첫 번째 µ
부터 두 번째 줄에 표시됩니다 . 프로그램의이 부분이 작동하는 방법은 다음과 같습니다.
“…’ḃ21+\iµØW“&;:' ”;“…’b58¤ị;0ị@
“…’ Base 250 representation of the gap sizes
ḃ21 Convert to bijective base 21
+\ Cumulative sum (converts gaps to indexes)
i Find the input in this list
µ Set as the new default for missing arguments
ØW Uppercase + lowercase alphabets (+ junk we ignore)
“&;:' ”; Prepend "&;:' "
“…’ Base 250 representation of the table entries
b58 Convert to base 58
¤ Parse the preceding two lines as a unit
i Use the table to index into the alphabets
;0 Append a zero
i@ Use {the value as of µ} to index into the table
형용사 기준 21은 기준 21과 비슷하지만 21은 유효한 숫자이고 0은 그렇지 않습니다. 이것은 두 개의 인접한 항목이 1의 갭을 갖는 것으로 계산하여 누적 합계를 통해 유효한 색인을 찾을 수 있기 때문에 더 편리한 인코딩입니다. 값을 보유하는 테이블 부분에는 58 개의 고유 값이 있으므로 먼저 58 개의 연속 정수로 디코딩 한 다음 조회 테이블을 사용하여 다시 사용되는 실제 문자로 매핑합니다. (대부분은 문자이므로 문자가 아닌 항목으로이 보조 조회 테이블을 &;:'
시작한 다음 대문자와 소문자 알파벳으로 시작하는 젤리 상수를 추가하십시오. 다른 정크도 있지만 신경 쓰지 않습니다. 그것에 대해.)
Jelly의 "인덱스를 찾을 수 없음"센티넬 값을 사용하여 목록으로 인덱싱하는 경우 목록의 마지막 요소를 리턴합니다. 따라서 필자는 누락 된 항목을 표시하기 위해보다 적절한 센티넬을 제공하기 위해 조회 테이블에 0 (정수 0, 테이블은 대부분 문자로 구성되었지만 정수 0)을 추가했습니다.
해시 기능
프로그램의 나머지 부분은 해시 함수입니다. 이것은 충분히 간단하게 시작됩니다.OḌ
; 이것은 입력 문자열을 ASCII 코드로 변환 한 다음 마지막 코드, 두 번째 코드의 10 배, 이전 코드의 100 배 등을 계산합니다 (Jelly에서는 매우 일반적으로 사용되기 때문에 매우 짧습니다) 문자열 → 정수 변환 기능). 그러나 모듈러스 연산을 통해이 해시를 직접 줄인 경우 다소 큰 테이블이 필요합니다. 대신 테이블을 줄이기 위해 일련의 작업으로 시작합니다. 그것들은 각각 다음과 같이 작동합니다 : 우리는 현재 해시 값의 다섯 번째 힘을 취합니다. 그런 다음 모듈로 값을 일정하게 줄입니다 (상수는 사용중인 작업에 따라 다릅니다). 이 체인은 다음과 같은 두 가지 방법으로 비용보다 (결과 체인 크기 자체를 인코딩해야하는 측면에서) 결과보다 더 많은 비용을 절감합니다 (결과 테이블 크기 축소 측면에서).매우 작은 (966이 아니라 3529 이상의 항목), 여러 단계의 사용은 이익 충돌 (이 많이 발생하지 않았지만, 하나 개의 충돌이 소개 더 많은 기회를 제공합니다 : 모두 Death
와 Yeenoghu
해시 (806)에 따라서 우리가 하나를 제거 할 수 있도록 허용 그들은 둘 다 갈 때 테이블에서 항목&
). 여기서 사용되는 모듈러스는 [3529, 2163, 1999, 1739, 1523, 1378, 1246, 1223, 1145, 966]입니다. 부수적으로, 제 5의 거듭 제곱으로 올리는 이유는 값을 직접 가져 가면 갭이 같은 크기를 유지하는 반면 지수는 갭을 움직이고 테이블이 더 균일하게 분포 될 수 있기 때문입니다. 로컬 최소값에 얽매이지 않고 체인 (보다 균일하게 분산 된 갭은 갭 크기의 더 엄격한 인코딩을 허용합니다). 이는 x ² = ( -x ) ²가 충돌을 일으키고 5가 3보다 낫다 는 사실을 방지하기 위해 이상한 힘 이어야합니다.
프로그램의 첫 번째 줄은 델타 인코딩을 사용하여 모듈러스 시퀀스를 인코딩합니다.
“…’;“…‘_\
“…’ Compressed integer list encoding, arbitrary sized integers
; Append
“…‘ Compressed integer list encoding, small integers (≤ 249)
_\ Take cumulative differences
프로그램의 나머지 부분 인 두 번째 줄의 시작은 해시 함수를 구현합니다.
OḌ;¢*5$%¥/
O Take ASCII codepoints
Ḍ "Convert from decimal", generalized to values outside the range 0-9
;¢ Append the table of moduli from the previous line
/ Then reduce by:
*5$ raising to the power 5 (parsing this as a group)
%¥ and modulusing by the right argument (parsing this as a group, too).
확인
이것은 프로그램이 올바르게 작동하는지 확인하기 위해 사용한 Perl 스크립트입니다.
use warnings;
use strict;
use utf8;
use IPC::Run qw/run/;
my %monsters = ("Aleax", "A", "Angel", "A", "Arch Priest", "@", "Archon", "A",
"Ashikaga Takauji", "@", "Asmodeus", "&", "Baalzebub", "&", "Chromatic Dragon",
"D", "Croesus", "@", "Cyclops", "H", "Dark One", "@", "Death", "&", "Demogorgon",
"&", "Dispater", "&", "Elvenking", "@", "Famine", "&", "Geryon", "&",
"Grand Master", "@", "Green-elf", "@", "Grey-elf", "@", "Hippocrates", "@",
"Ixoth", "D", "Juiblex", "&", "Keystone Kop", "K", "King Arthur", "@",
"Kop Kaptain", "K", "Kop Lieutenant", "K", "Kop Sergeant", "K", "Lord Carnarvon",
"@", "Lord Sato", "@", "Lord Surtur", "H", "Master Assassin", "@", "Master Kaen",
"@", "Master of Thieves", "@", "Medusa", "@", "Minion of Huhetotl", "&",
"Mordor orc", "o", "Nalzok", "&", "Nazgul", "W", "Neferet the Green", "@", "Norn",
"@", "Olog-hai", "T", "Oracle", "@", "Orcus", "&", "Orion", "@", "Pelias", "@",
"Pestilence", "&", "Scorpius", "s", "Shaman Karnov", "@", "Thoth Amon", "@",
"Twoflower", "@", "Uruk-hai", "o", "Vlad the Impaler", "V", "Wizard of Yendor",
"@", "Woodland-elf", "@", "Yeenoghu", "&", "abbot", "@", "acid blob", "b",
"acolyte", "@", "air elemental", "E", "aligned priest", "@", "ape", "Y",
"apprentice", "@", "arch-lich", "L", "archeologist", "@", "attendant", "@",
"baby black dragon", "D", "baby blue dragon", "D", "baby crocodile", ":",
"baby gray dragon", "D", "baby green dragon", "D", "baby long worm", "w",
"baby orange dragon", "D", "baby purple worm", "w", "baby red dragon", "D",
"baby silver dragon", "D", "baby white dragon", "D", "baby yellow dragon", "D",
"balrog", "&", "baluchitherium", "q", "barbarian", "@", "barbed devil", "&",
"barrow wight", "W", "bat", "B", "black dragon", "D", "black light", "y",
"black naga hatchling", "N", "black naga", "N", "black pudding", "P",
"black unicorn", "u", "blue dragon", "D", "blue jelly", "j", "bone devil", "&",
"brown mold", "F", "brown pudding", "P", "bugbear", "h", "captain", "@",
"carnivorous ape", "Y", "cave spider", "s", "caveman", "@", "cavewoman", "@",
"centipede", "s", "chameleon", ":", "chickatrice", "c", "chieftain", "@",
"clay golem", "'", "cobra", "S", "cockatrice", "c", "couatl", "A", "coyote", "d",
"crocodile", ":", "demilich", "L", "dingo", "d", "disenchanter", "R", "djinni",
"&", "dog", "d", "doppelganger", "@", "dust vortex", "v", "dwarf king", "h",
"dwarf lord", "h", "dwarf mummy", "M", "dwarf zombie", "Z", "dwarf", "h",
"earth elemental", "E", "electric eel", ";", "elf mummy", "M", "elf zombie", "Z",
"elf", "@", "elf-lord", "@", "energy vortex", "v", "erinys", "&", "ettin mummy",
"M", "ettin zombie", "Z", "ettin", "H", "fire ant", "a", "fire elemental", "E",
"fire giant", "H", "fire vortex", "v", "flaming sphere", "e", "flesh golem", "'",
"floating eye", "e", "fog cloud", "v", "forest centaur", "C", "fox", "d",
"freezing sphere", "e", "frost giant", "H", "gargoyle", "g", "garter snake", "S",
"gas spore", "e", "gecko", ":", "gelatinous cube", "b", "ghost", " ", "ghoul",
"Z", "giant ant", "a", "giant bat", "B", "giant beetle", "a", "giant eel", ";",
"giant mimic", "m", "giant mummy", "M", "giant rat", "r", "giant spider", "s",
"giant zombie", "Z", "giant", "H", "glass golem", "'", "glass piercer", "p",
"gnome king", "G", "gnome lord", "G", "gnome mummy", "M", "gnome zombie", "Z",
"gnome", "G", "gnomish wizard", "G", "goblin", "o", "gold golem", "'",
"golden naga hatchling", "N", "golden naga", "N", "gray dragon", "D", "gray ooze",
"P", "gray unicorn", "u", "green dragon", "D", "green mold", "F", "green slime",
"P", "gremlin", "g", "grid bug", "x", "guard", "@", "guardian naga hatchling",
"N", "guardian naga", "N", "guide", "@", "healer", "@", "hell hound pup", "d",
"hell hound", "d", "hezrou", "&", "high priest", "@", "hill giant", "H",
"hill orc", "o", "hobbit", "h", "hobgoblin", "o", "homunculus", "i",
"horned devil", "&", "horse", "u", "housecat", "f", "human mummy", "M",
"human zombie", "Z", "human", "@", "hunter", "@", "ice devil", "&", "ice troll",
"T", "ice vortex", "v", "iguana", ":", "imp", "i", "incubus", "&", "iron golem",
"'", "iron piercer", "p", "jabberwock", "J", "jackal", "d", "jaguar", "f",
"jellyfish", ";", "ki-rin", "A", "killer bee", "a", "kitten", "f", "knight", "@",
"kobold lord", "k", "kobold mummy", "M", "kobold shaman", "k", "kobold zombie",
"Z", "kobold", "k", "kraken", ";", "large cat", "f", "large dog", "d",
"large kobold", "k", "large mimic", "m", "leather golem", "'", "lemure", "i",
"leocrotta", "q", "leprechaun", "l", "lich", "L", "lichen", "F", "lieutenant",
"@", "little dog", "d", "lizard", ":", "long worm", "w", "lurker above", "t",
"lynx", "f", "mail daemon", "&", "manes", "i", "marilith", "&", "master lich",
"L", "master mind flayer", "h", "mastodon", "q", "mind flayer", "h", "minotaur",
"H", "monk", "@", "monkey", "Y", "mountain centaur", "C", "mountain nymph", "n",
"mumak", "q", "nalfeshnee", "&", "neanderthal", "@", "newt", ":", "ninja", "@",
"nurse", "@", "ochre jelly", "j", "ogre king", "O", "ogre lord", "O", "ogre", "O",
"orange dragon", "D", "orc mummy", "M", "orc shaman", "o", "orc zombie", "Z",
"orc", "o", "orc-captain", "o", "owlbear", "Y", "page", "@", "panther", "f",
"paper golem", "'", "piranha", ";", "pit fiend", "&", "pit viper", "S",
"plains centaur", "C", "pony", "u", "priest", "@", "priestess", "@", "prisoner",
"@", "purple worm", "w", "pyrolisk", "c", "python", "S", "quantum mechanic", "Q",
"quasit", "i", "queen bee", "a", "quivering blob", "b", "rabid rat", "r",
"ranger", "@", "raven", "B", "red dragon", "D", "red mold", "F",
"red naga hatchling", "N", "red naga", "N", "rock mole", "r", "rock piercer", "p",
"rock troll", "T", "rogue", "@", "rope golem", "'", "roshi", "@", "rothe", "q",
"rust monster", "R", "salamander", ":", "samurai", "@", "sandestin", "&",
"sasquatch", "Y", "scorpion", "s", "sergeant", "@", "sewer rat", "r", "shade", " ",
"shark", ";", "shocking sphere", "e", "shopkeeper", "@", "shrieker", "F",
"silver dragon", "D", "skeleton", "Z", "small mimic", "m", "snake", "S",
"soldier ant", "a", "soldier", "@", "spotted jelly", "j", "stalker", "E",
"steam vortex", "v", "stone giant", "H", "stone golem", "'", "storm giant", "H",
"straw golem", "'", "student", "@", "succubus", "&", "tengu", "i", "thug", "@",
"tiger", "f", "titan", "H", "titanothere", "q", "tourist", "@", "trapper", "t",
"troll", "T", "umber hulk", "U", "valkyrie", "@", "vampire bat", "B",
"vampire lord", "V", "vampire", "V", "violet fungus", "F", "vrock", "&", "warg",
"d", "warhorse", "u", "warrior", "@", "watch captain", "@", "watchman", "@",
"water demon", "&", "water elemental", "E", "water moccasin", "S", "water nymph",
"n", "water troll", "T", "werejackal", "d", "wererat", "r", "werewolf", "d",
"white dragon", "D", "white unicorn", "u", "winged gargoyle", "g",
"winter wolf cub", "d", "winter wolf", "d", "wizard", "@", "wolf", "d",
"wood golem", "'", "wood nymph", "n", "woodchuck", "r", "wraith", "W", "wumpus",
"q", "xan", "x", "xorn", "X", "yellow dragon", "D", "yellow light", "y",
"yellow mold", "F", "yeti", "Y", "zruty", "z");
for my $monster (sort keys %monsters) {
run ["./jelly", "fu", "monsters.j", $monster], \ "", \my $out;
print "$monster -> \"$out\" (",
($out ne $monsters{$monster} ? "in" : ""), "correct)\n";
}
mail daemon
> _ <