Сокращайте это государство США!


50

Учитывая одно из 50 названий штатов США слева в качестве входных данных, выведите двухбуквенный почтовый индекс, как показано справа:

Alabama         AL
Alaska          AK
Arizona         AZ
Arkansas        AR
California      CA
Colorado        CO
Connecticut     CT
Delaware        DE
Florida         FL
Georgia         GA
Hawaii          HI
Idaho           ID
Illinois        IL
Indiana         IN
Iowa            IA
Kansas          KS
Kentucky        KY
Louisiana       LA
Maine           ME
Maryland        MD
Massachusetts   MA
Michigan        MI
Minnesota       MN
Mississippi     MS
Missouri        MO
Montana         MT
Nebraska        NE
Nevada          NV
New Hampshire   NH
New Jersey      NJ
New Mexico      NM
New York        NY
North Carolina  NC
North Dakota    ND
Ohio            OH
Oklahoma        OK
Oregon          OR
Pennsylvania    PA
Rhode Island    RI
South Carolina  SC
South Dakota    SD
Tennessee       TN
Texas           TX
Utah            UT
Vermont         VT
Virginia        VA
Washington      WA
West Virginia   WV
Wisconsin       WI
Wyoming         WY

правила

  • Вход и выход чувствительны к регистру. Вы много не выводятся , например , Alдля Alabama.
  • Вы можете предположить, что вводом является одно из 50 названий состояний, показанных выше.
  • Вы не можете получить доступ к Интернету или использовать встроенные данные о состоянии (глядя на вас, Mathematica).

Отдельные списки входов и выходов можно найти в этом фрагменте (пожалуйста, не запускайте его, это просто для сжатия сообщения):

(Не набирая баллы) Очки Брауни, если вы также можете взять в District of Columbiaкачестве исходных данных и производства DC, Виргинские острова и т. Д. И т. Д.

счет

Это , поэтому выигрывает самый короткий код в байтах на каждом языке .

(Первоначально предложено ETHProductions)


11
Для тех, кому интересно узнать подход Mathematica:Entity[a="AdministrativeDivision",{#,"UnitedStates"}]@EntityProperty[a,"StateAbbreviation"]&
DavidC

12
@BetaDecay Вопросы, которые закрыты как не по теме, не являются полезными двойными целями.
Mego

7
@DavidC Вы можете сохранить 20байты: Entity["AdministrativeDivision",{#,"UnitedStates"}]@"StateAbbreviation"&:)
ngenisis

2
Предложить дополнительный кредит для включения других 12 двухсимвольных кодов в полный официальный список почтовых сокращений США: AA (ARMED FORCES AMERICAS), AE (ARMED FORCES EUROPE), AP (ARMED FORCES PACIFIC), AS (AMERICAN SAMOA), DC (ОКРУГ КОЛУМБИЯ), FM (ФЕДЕРАЛЬНЫЕ ГОСУДАРСТВА МИКРОНЕЗИИ), GU (ГУАМ), MH (ОСТРОВА МАРШАЛЛ), MP (СЕВЕРНЫЕ МАРИАНСКИЕ ОСТРОВА), PR (ПУЭРТО РИКО), PW (PALAU), VI (ВИРДЖИНСКИЕ ОСТРОВА).
Джо Снайдер

2
Да, это не дурак.
Кристофер

Ответы:


25

Javascript, 124 117 байт

(сэкономлено 7 байт благодаря hvd)

x=>/.+[A-Z]|A..[sz]k?|M.ss.s?|M[io]n?t?|Nev?|[AFIOUW][^o]|T..|.+/.exec(x)[0].replace(/(.).*(.)/,'$1$2').toUpperCase()

Объяснение:

  • Регулярное выражение находит совпадение с первой и последней буквами двух букв аббревиатуры
  • Первая часть соответствует штатам с более чем двумя словами (включая округ Колумбия)
  • Вторая часть матчей Аляски и Аризоны
  • Третья часть матча Массачусетс, Миссисипи и Миссури
  • Четвертая часть матча Мичиган, Миннесота и Монтана
  • Пятая часть соответствует Небраске и Неваде
  • Шестая часть соответствует всем оставшимся штатам, сокращенным до их первых двух букв, с особым случаем, чтобы исключить Айову
  • Седьмая часть соответствует всем остальным штатам, сокращенным до их первой и третьей букв
  • Восьмая часть соответствует всем остальным, которые сокращены до их первых и последних букв
  • Тогда это просто случай удаления этих букв и использования заглавных букв.
  • Также соответствует Пуэрто-Рико и Американскому Самоа, но не Гуаму, Марианским островам или Виргинским островам США.

Вау, это здорово! +1!
NoOneIsHere

3
Приятно! Еще несколько возможностей: инициализация [A-Z]не нужна, поскольку известно, что ввод действителен. Особый случай Айовы может быть сокращен, чтобы [AFIOUW][^o]исключить это, оставляя это для финала .+.
HVd

1
Ваш механизм регулярных выражений настолько эффективен по сравнению с моим ... хотелось бы, чтобы был способ заставить его работать с моим более коротким регулярным выражением. Но они построены на таких разных принципах.
Стив Беннет

1
Ну, есть немало странных по-своему. Есть хорошая коллекция, которая соответствует правилам «первое и последнее» и «первые два» (Колорадо, Делавэр, Калифорния ...), но затем Миссисипи (MS) разрушает ее.
Стив Беннет

1
101: s=>s[0]+/.+[A-Zz]|Nev?|.*sk|M.ss.s?|M[io]n?t?|[AFIOUW][^o]|Te.|.+/.exec(s)[0].slice(-1).toUpperCase()мы можем добраться до 100? :)
Стив Беннетт

22

Javascript, 137 135 134 132 113 110 108 101 99 94 93 92 байта

Это основано на решении HP Williams, с некоторыми улучшениями вне регулярных выражений и несколькими изменениями в нем.

s=>s[0]+
/.*( .|z)|...s.s?|T..|M[i-t]+|[AFINOUW][^o]v?|.*/
.exec(s)[0].slice(-1).toUpperCase()

(Разрывы строк только для удобства чтения)

Комментарий к регулярному выражению:

.*( .|z)|      // Two-or-three word states, plus Arizona
...s.s?|       // Mississippi, Missouri, Massachussetts, Alaska, and (non-harmfully) Kansas
M[i-t]+|       // Montana, Minnesota, Michigan
[AFINOUW][^o]v?|  // All the other first-two-letter states, avoiding Iowa, plus Nevada
T‌​..|           // Tennessee, Texas
.+             // Everything else is first-and-last

Бессмысленное альтернативное регулярное выражение (той же длины):

/...(a$|z|s.s?|.* .)|M[i-t]+|T..|[AFINOUW].v?|.*/  

история

94

s=>s[0]+/.*( .|z)|...s.s?|M[io]n?t?|[AFIOUWN][^o]v?|T..|.*/
.exec(s)[0].slice(-1).toUpperCase()

99

s=>s[0]+/.*( .|z|l.*k)|T..|M.ss.s?|M[io]n?t?|[AFIOUWN][^o]v?|.*/
.exec(s)[0].slice(-1).toUpperCase()

101

s=>s[0]+/.+[A-Zz]|Nev?|.*sk|M.ss.s?|M[io]n?t?|[AFIOUW][^o]|T‌​e.|.+/
.exec(s)[0].sl‌​ice(-1).toUpperCase(‌​)

108

 s=>s[0]+/MI(N|SSO|S)|[CDGHKLPV].*|.* .|.*[XZV]|.*?N[NTE]|.*(SK|D$|WA)|../
.exec(s.toUpperCase())[0].slice(-1)

110

s=>s[0]+/MI(N|SSO|S)|[CGHKLPV].*|.* .|.*[XZV]|.*?N[NTE]|.*(SK|[ED]$|WA)|../
.exec(s.toUpperCase())[0].slice(-1)

113

s=>s[0]+/^MI(N|SSO|S)|^[CGHKLPV].*|.*?( .|[XZV])|.*?N[NTE]|.*(SK|[ED]$|WA)|../
.exec(s.toUpperCase())[0].slice(-1)

132

s=>(S=s.toUpperCase(),' ._SSO_^MI[NS]_^[CGHKLPV].*_.V_N[TNE]_SK_[ED]$_WA_Z_X_..'
.split`_`.some(p=>s=S.match(p)),S[0]+s[0].slice(-1))

134

s=>' ._SSO_^MI[NS]_^[CGHKLPV].*_.V_N[TNE]_SK_E$_D$_WA_Z_X_..'.split`_`
.map(p=>s=(z=s.toUpperCase().match(p))?s[0]+z[0].slice(-1):s)&&s

135

s=>' ._SSO_^MI[NS]_LASK_^[CGHKLPV].*_NT_EN_[DE]$_WA_.[XVZ]_..'.split`_`
.map(p=>s=(z=s.toUpperCase().match(p))?s[0]+z[0].slice(-1):s)&&s

137

s=>' ._OWA_SSO_ONT_^MI[NS]_LASK_^[CGHKLPV].*_EN_[DE]$_.[XVZ]_..'.split`_`.
map(p=>s=(z=s.toUpperCase().match(p))?s[0]+z[0].slice(-1):s)&&s

Это просто безумие, хотелось бы снова поднять голос.
ETHproductions

Не смотри сейчас! 99!
Стив Беннетт

94. Совершенно сумасшедший. Я обнаружил эту оптимизацию ( ...s.s?захватывает Миссисипи, Миссури, Массачусетс и Аляску) случайно. На самом деле я находился в процессе перемещения .*skфрагмента куда-то еще, и тесты просто запускались и проходили, а фрагмента нигде не было. Легче всего получить 5 персонажей!
Стив Беннетт

Ничего себе, и я только что понял, что ...s.s?это также непреднамеренно соответствует Канзасу, и, чудом, все еще дает правильный результат.
Стив Беннетт

И еще один персонаж с M[onti]+. Так странно: если состояние начинается с M, то вторая буква является последней в последовательности, по крайней мере, одного o, n, t или i. Очень странный способ захватить Мичиган, Миннесоту или Монтану.
Стив Беннетт

20

JavaScript (ES6), 156 136 байт

s=>s[0]+'.KT..N.VEA.XVL.H.TZ.AA..I.EADATO.JTISRDIYOI.DALA.Y.KE.C.D.R.YAS.NM...C.L...N'[parseInt(s.split` `.join``,36)%359%248*8%99*3%83]

демонстрация


1
Является ли это грубым, чтобы быть оптимальным, используя этот метод?
Только для ASCII

2
@ ASCII-only Это брутфорс на произвольных диапазонах, поэтому он гарантированно будет оптимальным для X MOD[50-1000] MOD[50-1000] MOD[50-100]. Но это .slice(1)была ошибка. В настоящее время снова работает на всю строку.
Арно

2
Не могли бы вы объяснить новичку, что это делает?
Hankrecords

1
@Hankrecords Конечно, сделаем. (Но я сейчас в поезде с ограниченным доступом в Интернет.)
Арно

1
сейчас у меня 135!
Стив Беннет

17

Желе , 75 байт

³Oḅ⁹%⁽qġ%14ị⁽"wB¤Ḥ
“¿ØƈṢḍw÷S=)µZṂ÷ĿæÆɱ»Ḳiµ%2+3¢⁸?
e“\B“½ƈN»ȧ5ȯÇ’
i⁶ȯÇ‘ịṭḢŒu

Попробуйте онлайн!

... или посмотрите набор тестов. Обратите внимание, что нужно было внести небольшое изменение, чтобы запустить полную программу для нескольких входов за один раз (я поменял атом ввода программы, ³для вызова из регистра ®, один и установил регистр каждому названию штата по очереди).

Как?

Вычисляет индекс для использования для второго символа почтового индекса, добавляет его к первому символу и в верхнем регистре результат.

Сначала находит индекс пробела (или 0, если не найден);

Еще проверяет, Аляска ли это или Миссури (получая 5 для kили o);

Иначе находит индекс состояния ввода в списке Arizona Minnesota Mississippi Nevada Montana Texas Tennessee(или 0, если не найден) - если это так, он принимает индекс mod 2 плюс 3 (для z n s v t x n);

Иначе, преобразует строку в ординалы, преобразовывает ее из базы 256, находит остаток после деления на 29487, находит остаток после деления на 14 и использует ее для индексации в двоичном представлении 9620 и удваивает результат - получая 0 для штатов, которые используют свою последнюю букву и 2 для тех, которые используют свою вторую букву.

Все, кроме самого первого случая, увеличиваются, а результирующее значение уменьшается (увеличивая индекс пространства, найденный на единицу).

i⁶ȯÇ‘ịṭḢŒu - Main link: state string
 ⁶         - space character
i          - first index (of a space character in the state) or 0 if not found  (n-1 or 0)
   Ç       - call link 3 as a monad  (get n-1 in other cases)
  ȯ        - logical or  (yielding n-1)
    ‘      - increment   (yielding n)
     ị     - index into the state string (get the nth character)
       Ḣ   - head the state string (get the first character)
      ṭ    - tack
        Œu - convert to uppercase
           - implicit print

e“\B“½ƈN»ȧ5ȯÇ’ - Link 3: n-5 or ... : state string
 “\B“½ƈN»      - ["Alaska","Missouri"]
e              - exists in? (1 if so, 0 if not)
          5    - 5
         ȧ     - logical and
            Ç  - call link 2 as a monad
           ȯ   - logical or
             ’ - decrement

“¿ØƈṢḍw÷S=)µZṂ÷ĿæÆɱ»Ḳiµ%2+3¢⁸? - Link 2: n = 3 or n = 4 or ... : state string
“¿ØƈṢḍw÷S=)µZṂ÷ĿæÆɱ»           - "Arizona Minnesota Mississippi Nevada Montana Texas Tennessee"
                    Ḳ          - split at spaces
                     i         - first index of state string in that list or 0
                      µ        - monadic chain separation (call that i)
                             ? - if: 
                            ⁸  -   link's left argument, i
                               - then:
                       %2      -   mod 2
                         +3    -   plus 3  - odd entries to 4: AriZona, MisSissippi, MonTana, TenNessee
                               -            even entries to 3: MiNnesota, NeVada, TeXas
                               - else:
                           ¢   -   call link 1 as a nilad

³Oḅ⁹%⁽qġ%14ị⁽"wB¤Ḥ - Link 1 ...n=2 or n=0: no arguments
³                  - program's 1st input    e.g. Iowa          or Ohio
 O                 - cast to ordinals            [73,111,119,97]  [79, 104, 105, 111]
   ⁹               - 256
  ḅ                - convert from base           1232041825       1332242799
     ⁽qġ           - 29487
    %              - modulo                      15991            20139
        %14        - modulo 14                   3                7
                ¤  - nilad followed by link(s) as a nilad:
            ⁽"w    -   9620                     V       V
               B   -   convert to binary = [1,0,0,1,0,1,1,0,0,1,0,1,0,0]
           ị       - index into                  0                1
                 Ḥ - double                      0                2
                   -   ...0th index of Iowa is 'a', 2nd of Ohio is 'h'

1
Это самое длинное желе, которое я когда-либо видел =)
caird coinheringaahing

11

Python 2 , 191 байт

lambda s:s[0]+("KZD"*5+"HNTD"*5+"AYY"*4+"__L_O_VTA_I__A_T_RS_KA__S_"+"MOO"*5+"I_C_"+"AE"*6+"_I_D__A_"+"EDL"*5+"HV_A"+"IR"*7+"XC"*6+"E____N__YJ_YT___L")[reduce(lambda a,x:a+ord(x)^24,s,0)%174]

Попробуйте онлайн!

Использует простую хэш-функцию, чтобы найти второй символ аббревиатуры.


11

Python 2, 94 90 байт

lambda s:s[0]+s[(19**9*0x4710b8f6019c1b61deca10eef13b1>>hash(s)%8199472%52*3&7)+1].upper()

Попробуйте онлайн

(Только Python 2, поскольку хэши Python 3 нестабильны, а также вы не можете хэшировать строку, не превращая ее в байты.)

Работает со всеми 50 штатами, а также в качестве бонусного округа Колумбия и Пуэрто-Рико.

Можно было бы сохранить один байт, написав число в базе-36: int("5clu7x0aixb0pelmpugv5iiibphrpf",36). Я жду, чтобы увидеть, могу ли я придумать более креативное решение.

Обновить:

Поскольку в хэше 12 неиспользуемых позиций цифр, есть 2 36 возможных номеров, которые будут работать. Казалось разумным полагать, что у одного из них будет главный фактор с большим показателем. Для любого заданного простого числа и показателя степени найти значение довольно быстро; Мне удалось найти одно с коэффициентом 19 9 , уменьшив размер выражения, необходимого для представления числа, на четыре байта.

По сути, это та же процедура, что и в моем ответе на C, но с использованием Python. Поскольку базовая хеш-функция отличается, мне пришлось найти другую функцию сокращения, которая оказывается mod 52 вместо mod 54. Но самая большая экономия по сравнению с C связана с возможностью использования bignums для кодирования вектора, и, конечно, тот факт, что стандартом для Python является то, что можно использовать лямбда-литерал вместо полной программы.


9

Retina , 113 81 80 77 70 68 байт

M1!`.+[A-Zz]|...s.s?|M[io]n?t?|[AFIOUWN][^o]v?|T..|.*
\B.*(?=.)

T`l`L

Попробуйте онлайн! Включает в себя все 51 тестовых случаев. Сохранено 32 байта путем присвоения регулярного выражения @ JörgHülsermann, которое находит вторую букву (с настройкой для поддержки DC; редактирование: сохранено 1 байт благодаря @ JörgHülsermann). Сэкономили 3 байта, переключившись на регулярное выражение @ SteveBennett из своего комментария в ответ @ HPWilliam. Сохранено 7 9 байт, еще раз спасибо @SteveBennett. Другие буквы затем удаляются, а строка в верхнем регистре.


Очень хорошо, я бы не подумал, что вы можете получить набор полностью сменных струн.
Colsw

@ConnorLSW eбыл самым хлопотным, правда.
Нил

@ JörgHülsermann Спасибо за ответную услугу!
Нил

@ JörgHülsermann О, тогда я смогу сохранить еще один байт?
Нил

1
Подождите, Индиан действительно становится ID. Вы можете исправить это, просто добавив $ после d. (Возможно, вы захотите использовать автоматическое тестирование - у меня есть скрипт, который постоянно проверяет все 50 случаев.)
Стив Беннетт,

8

PHP> = 7,1, 113 байт

<?=($a=$argn)[0],ucfirst(preg_match('#[vxz]| .|owa|lask|[CGHKLPV].*|ssi?.|n(n|t|[de]$)#',$a,$t)?$t[0][-1]:$a[1]);

Онлайн версия

Забастовки проходят через более раннее начало матча

([vxz])Матчи Аризона, Невада, Нью-Мексико, Пенсильвания, Техас,

(.) (один пробел раньше) соответствует Нью-Гемпширу, Нью-Джерси, Нью-Мексико, Нью-Йорку, Северной Каролине, Северной Дакоте, Род-Айленду, Южной Каролине, Южной Дакоте, Западной Вирджинии

[CGHKLPV].*(.)матчи Калифорния, Колорадо, Коннектикут, Джорджия, Гавайи, Канзас, Кентукки, Луизиана, Нью-Гемпшир , Северная Каролина, Пенсильвания, Южная Каролина , Вермонт, Вирджиния, Западная Вирджиния

ow(a) матч Айова

las(k) соответствовать Аляске

ssi?(.)матчи Массачусетс, Миссисипи, Миссури, Теннесси

n(n|t|[de]$)матчи Коннектикут, Кентукки, Мэн, Мэриленд, Миннесота, Монтана, Пенсильвания, Род-Айленд, Теннесси, Вермонт

Нет совпадения для этих штатов, поэтому мы берем первые две буквы: Алабама, Арканзас, Делавэр, Флорида, Айдахо, Иллинойс, Индиана, Мичиган, Небраска, Огайо, Оклахома, Орегон, Юта, Вашингтон, Висконсин, Вайоминг

Впервые я использую этот Regex Subpatter ?| с, чтобы хранить обратные ссылки в одном.

Поддержка округа Колумбия

Заменить (.)на ([^o])+3 байта

Попробуйте онлайн!

PHP, 150 байт

<?=($t=preg_replace("#.\K\w+ |las|ri|nec|eorgi|awa|ow|[aio]ni?|e(?=n|v|x)|ntuck|ouisi|a?in|arylan|issi?|nnsylv|erm|irg#","",$argn))[0],ucfirst($t[1]);

Попробуйте онлайн! Testcases


3
Не n|t|байт ли короче [nt]|?
Нил

@ Нейл Да, это так. Я не понимаю этого. Спасибо
Йорг Хюльсерманн

7

PHP, 887 854 байта

<?=array_combine(['Alabama','Alaska','Arizona','Arkansas','California','Colorado','Connecticut','Delaware','Florida','Georgia','Hawaii','Idaho','Illinois','Indiana','Iowa','Kansas','Kentucky','Louisiana','Maine','Maryland','Massachusetts','Michigan','Minnesota','Mississippi','Missouri','Montana','Nebraska','Nevada','New Hampshire','New Jersey','New Mexico','New York','North Carolina','North Dakota','Ohio','Oklahoma','Oregon','Pennsylvania','Rhode Island','South Carolina','South Dakota','Tennessee','Texas','Utah','Vermont','Virginia','Washington','West Virginia','Wisconsin','Wyoming'],['AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY'])[$argv[1]];

Попробуйте онлайн!

Первый таймер, ура!


1
Таким образом, немного поиграл в массиве значения с пробелом или там, где правильно удалена вторая буква. И $argv[1]заменяется на $argn sandbox.onlinephpfunctions.com/code/…
Йорг Хюльсерманн

@ JörgHülsermann большое спасибо! Мне очень нравятся ваши ответы здесь на Codegolf в php!
Иванка Тодорова

Я только немного света против других людей здесь. Усилия по обучению хороши, если кто-то находит улучшение. Я надеюсь, что вы ответите больше вопросов в будущем
Йорг Хюльсерманн

7

C 945 937 718 711 660 616 байт

Сохранено 219 байтов благодаря ASCII-только.

struct{int*a,b;}m[]={"laba",76,"lask",75,"rizo",90,"rkan",82,"alif",65,"olor",79,"onne",84,"elaw",69,"lori",76,"eorg",65,"awai",73,"daho",68,"llin",76,"ndia",78,"owa",65,"ansa",83,"entu",89,"ouis",65,"aine",69,"aryl",68,"assa",65,"ichi",73,"inne",78,"issi",83,"isso",79,"onta",84,"ebra",69,"evad",86,"ew H",72,"ew J",74,"ew M",77,"ew Y",89,"orth",67,"orth",68,"hio",72,"klah",75,"rego",82,"enns",65,"hode",73,"outh",67,"outh",68,"enne",78,"exas",88,"tah",84,"ermo",84,"irgi",65,"ashi",65,"est ",86,"isco",73,"yomi",89};
i;char b[99];main(){gets(b);putchar(*b);for(;m[i].a;i++)if(!strncmp(m[i].a,b+1,4))puts(&m[i].b);}

Новая строка не нужна, только для отображения. Принимает состояние в качестве ввода. Попробуйте онлайн!

Как это устроено:

  • struct{int*a,b;}m[]=...объявляет карту mс двумя значениями - четырехбайтовой строкой и одним символом. Это используется в цикле сравнения, который сравнивает индексы со второго по пятый с char*aкартой.
  • gets(b)считывает строку b. Это будет государство сокращать.
  • putchar(*b) печатает первый символ этой строки, так как каждая аббревиатура начинается с первой буквы состояния.
  • for(;m[i].a;i++)перебирает каждое значение карты. (Это может быть сокращено.)
  • if(!strncmp(m[i].a,b+1,4))сравнивает текущее значение карты со вторым по пятый символами b(сокращенное состояние). Это потому, что единственные различия заключаются в первых пяти символах, но мы уже напечатали первый символ.
  • puts(&m[i].b); печатает вторую букву аббревиатуры (если имя штата совпадает с текущим значением карты) и символ новой строки.

Похоже, что это приводит к неправильному выводу для штатов Север * / Юг *.
Феликс Домбек

6

C 148 141 байт

main(){char s[99];gets(s);printf("%c%c\n",*s,s["-2-1--561-1-62--642138364---4142--1416--67-7131-111-7-246"[*(int*)(s+1)%663694%57]-48]&95);}

*(int*)(s+1)считает входной символ со второго по пятый целым числом; это целое число затем хэшируется в 0-56, используя хэш i%663694%57. Затем значение хэширования ищется в векторе смещений, которые представляют местоположение второй буквы аббревиатуры. Я выбрал именно эти четыре байта, потому что (1) Миссури и Миссисипи сначала различаются по пятому символу, и (2) в некоторых штатах есть только четыре символа. В C вы можете использовать терминатор NUL, но ничего кроме этого не является надежным. (Это хэширует оба Севера к одному и тому же значению, а также оба Юга. Но это не имеет значения, потому что для каждого из них соответствующее смещение равно 6).

Так получилось, что этот конкретный хеш дает правильную позицию для вторых букв аббревиатур округа Колумбия, Пуэрто-Рико и «Виргинских островов» (набираемых таким образом, а не как «Виргинские острова США», потому что алгоритм настаивает, что первый символ аббревиатуры будет первым символом имени).

Константы 663694 и 57 были найдены с помощью автоматического теста; 57 был наименьшим диапазоном хэшей, который я нашел. (Первая версия использовала 380085 и 63, но когда я расширил тестовый диапазон, я нашел новую.) Кажется, что существует немного меньший хэш, если добавлен код для «используйте последний символ в имени»; к сожалению, синтаксис C для выбора последнего символа слишком многословен, чтобы сделать это полезным.

Существует только 8 различных смещений, поэтому они могли быть сохранены в 171-битной (3 * 57) таблице поиска с тремя битами на запись. Но я не мог придумать, как эффективно вставить эти биты в программу. Шестнадцатеричное кодирование потребует около одного символа на четыре бита плюс 0xпрефиксы. Я не мог сделать лучше, чем 151 байт, что намного длиннее, чем строковая версия. Если бы 171 бит можно было как-то вставить в виде необработанных октетов, они бы занимали 22 байта, так что может быть решение, но чтение файла неуклюже.


4

На самом деле , 181 байт

2"OHCALAGAMAWVFLNVILMNMOMIRINCDEMTMEINWANYTXORNEOKIDAZNMUTNDMDVAKYSDPAARWYNHIAMSALNJAKTNHIKSVTWICOSCCT"╪"âäà♠îÉæô↨→←∟♣áíå*,▓/12│┤94▼╛?DE╞G╚╠╬ST╒WXßb;Θoq╙|⌂"♂┘Z⌠i≈┐⌡MXO;rR5♀ⁿ*:236@%└

Это решение ожидает ввода в виде строки в кавычках.

Попробуйте онлайн!

объяснение

В этом решении используется та же стратегия хеширования, что и в моем решении Python 3 . Для краткости я опущу объяснение того, как вычисляется хэш и почему он был выбран (перейдите к другому ответу, если хотите этот бит).

Также для краткости, я собираюсь опустить содержимое очень длинных строк, так как иначе объяснение было бы нечитаемым.

2"..."╪"..."♂┘Z⌠i≈┐⌡MXO;rR5♀ⁿ*:236@%└
2"..."╪                                state abbreviations (push the long string, split into length-2 chunks)
       "..."♂┘                         hash values for the state names (a string of CP437-encoded characters, converted to their CP437 ordinals)
              Z                        zip the two lists
               ⌠i≈┐⌡M                  for each pair:
                i                        flatten the pair
                 ≈                       convert hash value to int
                  ┐                      store abbreviation at the register numbered by the hash value
                     X                 discard the now-empty list
                      O                convert input string to list of ASCII ordinals
                       ;rR             range(len(ordinal_list)), reversed
                          5♀ⁿ          5**i mapped over that range
                             *         dot product of powers of 5 and ordinal list
                              :236@%   mod by 236
                                    └  push value in that register

3

Python 3 , 230 байт

lambda s:chr(s[0])+'IA%%L!NOI!M%!E.N!Y.XR.Z$D.I!.D$DA.D%!.HA!LJ%.N%‌​$T.I%!C!T!.HAAT$.A!.‌​VL.V%$CE%%AEK%.T$!.Y‌​.A!.R.Y$O.S%!.K$!.S'‌​.replace('%','$$').r‌​eplace('$','!!').rep‌​lace('!','..')[sum(c‌​*5**i for i,c in enumerate(s[::-1]))%236-5]

Попробуйте онлайн!

Ввод ожидается в виде байтового объекта (байтовой строки, а не строки Юникода).

Спасибо Джонатону Аллану за нелепое количество байтов

объяснение

Каждое имя состояния хешируется в целое число aпутем применения хэша a = sum(o*5**i) % 236(где o- порядковый номер ASCII символа и iего индекс в строке, начиная с конца). Модуль 236был выбран потому, что это наименьший модуль, при котором все значения хеш-функции различаются для 50 названий штатов США. Эти хэши затем сопоставляются с аббревиатурами состояний, и результирующий словарь (сжатый с использованием подстановки строк) используется для поиска аббревиатуры по имени состояния (хеширование его для получения подходящего ключа).


Сохранить 179 байтов сlambda s:chr(s[0])+'.....IA................L..NOI..M..........E.N..Y.XR.Z....D.I...D....DA.D...........HA..LJ.........N............T.I..........C..T...HAAT.....A...VL.V............CE................AEK.........T.......Y.A...R.Y....O.S...........K.......S'[sum(c*5**i for i,c in enumerate(s[::-1]))%236]
Джонатан Аллан

... и еще 51, lambda s:chr(s[0])+'IA%%L!NOI!M%!E.N!Y.XR.Z$D.I!.D$DA.D%!.HA!LJ%.N%$T.I%!C!T!.HAAT$.A!.VL.V%$CE%%AEK%.T$!.Y.A!.R.Y$O.S%!.K$!.S'.replace('%','$$').replace('$','!!').replace('!','..')[sum(c*5**i for i,c in enumerate(s[::-1]))%236-5]
Джонатан Аллан

Я удивлен, что подсчет в обратном направлении стоит меньше байтов, чем хэш-функция, которая рассчитывает вперёд - но я не могу найти один с небольшой игрой
Крис Х

1
@ChrisH Я думал, что нашел один, но сжатая строка дороже.
Mego

2

Рубин, 106 103 байта

->s{s[0]+(s=~/ /?$'[0]:s[(j="()6>P_ac;?.O}AFLKMrS".index((s.sum%136%95+32).chr))?j>7?j/4:-1:1]).upcase}

Если на входе есть пробел, вторая выходная буква будет той, что после пробела. Else ...

Хеш сумма всех символов на входе, чтобы получить символ, чей индекс в магической строке указывает индекс второй выходной буквы во входной строке, в соответствии с формулой j>8?j/4:-1(-1 означает конец.). Если хеш дает символ, которого нет в магической строке, вторая буква является второй буквой ввода.

В качестве объяснения магической строки ниже приведены хеш-символы и буквенные индексы, которые они кодируют. Обратите внимание, что Делавэр появляется, хотя вторая буква будет делать - это потому, что его хэш-код конфликтует с Кентукки. К счастью, последняя буква Делавера такая же, как и вторая.

Letter(index)
Last  (-1)  (-MD    )-VA    6-GA-LA  >-DE-KY    P-PA    _-CT    a-KS    c-VT
3rd    (2)  ;-TN    ?-MN    .-TX     O-NV
4th    (3)  }-MS    A-IA    F-MT     L-AZ
5th    (4)  K-MO    M-AK    r-ME     S-HI 

Неуправляемый в тестовой программе

a="Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
New Hampshire
New Jersey
New Mexico
New York
North Carolina
North Dakota
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode Island
South Carolina
South Dakota
Tennessee
Texas
Utah
Vermont
Virginia
Washington
West Virginia
Wisconsin
Wyoming".split($/)

f=->s{                                                            #String argument s.
  s[0]+(                                                          #Return character s[0] +
    s=~/ /?$'[0]:                                                 #if s contains a space, 1st character after space, ELSE
      s[(j="()6>P_ac;?.O}AFLKMrS".index((s.sum%136%95+32).chr))?  #if (sum of ascii codes, mod 136 mod 95 +32).chr in the magic string
        j>7?j/4:-1:                                                 #return s[j/4] if j>7 else return s[-1] ELSE
      1]                                                          #if not in the magic string, return s[1].
  ).upcase                                                        #Convert the second character to uppercase if needed.
}


a.map{|i|p [i,f[i]]}

2

/// , 619 608 байт

/2/~M//@/~South //1/~North //!/~New //~/\/\///Alabama/AL~Alaska/AK~Arizona/AZ~Arkansas/AR~California/CA~Connecticut/CT~Delaware/DE~Florida/FL~Georgia/GA~Hawaii/HI~Idaho/ID~Illinois/IL~Indiana/IN~Iowa/IA~Kansas/KS~Kentucky/KY~Louisiana/LA2aine/ME2aryland/MD2assachusetts/MA2ichigan/MI2innesota/MN2ississippi/MS2issouri/MO2ontana/MT~Nebraska/NE~Nevada/NV!Hampshire/NH!Jersey/NJ!Mexico/NM!York/NY1Carolina/NC1Dakota/ND~Ohio/OH~Oklahoma/OK~Oregon/OR~Pennsylvania/PA~Rhode Island/RI@Carolina/SC@Dakota/SD~Tennessee/TN~Texas/TX~Utah/UT~Vermont/VT~Virginia/VA~Washington/WA~West Virginia/WV~Wisconsin/WI~Wyoming/WY/

Попробуйте онлайн!

Поскольку нет другого способа ввода ввода в ///, он идет в конце программы. Просто добавьте желаемый вход в программу.

Сэкономили 11 байт, сделав больше замен, в соответствии с рекомендациями @SteveBennett


Вероятно, есть несколько шаблонов, которые вы можете заменить несколько раз одновременно, например, «Новый» и «Акота». Раздражает, что вы не можете сделать намного умнее, как удаление разделов имен состояний, потому что преобразование оставшегося символа в верхний регистр стоит слишком дорого ...
Стив Беннетт

@SteveBennett Отредактировано, спасибо!
Товарищ SparklePony


1

TAESGL , 386 байт

B=«ōďā,AL,ņćđ,AK,ķċđ,AZ,ćōē,AR,ďċđ,CA,ĭāď,CO,ŕĭ,CT,ćđēą,DE,ĕŕ,FL,īĭ,GA,ńāē,HI,ćĉďą,ID,ĭċď,IL,ľđā,ţ,ńĕĕ,IA,ķő,KS,ŏĝ,KY,ŏĕĕ,LA,ŏđć,ME,ņāē,MD,ńđā,MA,īđą,MI,ļēď,MN,ŕğ,MS,ňė,MO,ććĕĉ,MT,ćċćĉ,NE,ŕēď,NV,ň ćŋā,NH,ň ĩēđ,NJ,ň ğĕċ,NM,ň ĉĝ,NY,ćņ ġĉă,NC,ćņ ńċą,ND,ĩēą,OH,ŋĺ,OK,ļķ,OR,ĺđď,PA,ĉĉğ đēā,RI,ōċ ġĉă,SC,ōċ ńċą,SD,ňďą,TN,ċĕď,TX,ōđą,UT,ćđāā,VT,ğğ,VA,ďĉē,WA,ĉĉć ğğ,WV,ľēđ,WI,ĉĩĕ,WY»Ĵ",";B[BĪA)+1

переводчик

Очень простое сжатие имен состояний, добавленных в массив с сокращениями.


1

Japt, 383 байта

Сжатие первой строки может быть улучшено, экспериментируя с порядком букв.

g +`lkzÇUaidlnyaÀÍ¥evhjmycdhkÎödnxttaaviy`g`alabaµ
Ã2ka
iza
kÂ6s
Öâfnia
åªv
¬nש
Ü.Ø
fÓQ»
gegia
°ii
i»
ÅJno
Äa
Å0
kÂ6s
kÀ_cky
lia
Úpe
æ¯À
ÚUaÖ³etts
Úòig
·nÌta
æ«7ppi
æ¬
Úa
ßka
va»
w mp¢i
w jÀ y
w ´xi¬
w yk
Íh ÖÚ¦na
Íh »kota
oo
oklaÊá
eg
pnsylvia
r¸ Ó
Ñh ÖÚ¦na
Ñh »kota
âÊte
x
©ah
vÚ
virgia
Øgn
ØÙ virgia
æÈ;n
wyÇg`·bUv) u

Попробуйте онлайн


1

Mathematica, 138 140 134 байт

+2 байта - обнаружена ошибка (необходимо смещение массива 1, а не 0)

-6 байт - нашел лучший хеш

#~StringTake~1<>"R_ATE__IN_COI_J_I_SLNAT_Y_Y_HKOAE__SAA_DDLM_RVAH_XDTVA__I_N_EA_T_DY_C_KZL"~StringTake~{1+Hash@#~Mod~89866736~Mod~73}&

Подобно другим, он берет имя и принимает первую букву. Затем он применяет хэш Mathematica по умолчанию, затем применяет к нему два модуля " Hash@#~Mod~89866736~Mod~73", чтобы получить уникальный номер для каждого состояния. Это значение затем ищется в строке для генерации второй буквы.

Вероятно, можно играть в гольф больше, но пространство поиска для Mathematica огромно. Дублированные вторые буквы не учитывались при поиске по хешу. _символы представляют потерянные значения в строке. Теоретически вы можете получить строку только до 19 символов, но найти пользовательский хеш для создания этого будет кошмаром.


1

Perl 5, 150 148 байт (147 + 1)

Это ни в коем случае не оптимально, но делает свою работу. Требуется -nфлаг командной строки.

s/las//;s/ai?n//;s/[oie]n|ri//;s/e([vx])/$1/;s/issi?//;s/(.).+ /\1/;/(.)(.)/;/^([^W]).*(?:[cogavn][wiku]|[ir][ys][li]|rm)([adyti])$/;print uc"$1$2"

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.