# Abbreviate that US state!

Given one of the 50 U.S. state names on the left as input, output its two-letter postal code as shown to the right:

Alabama         AL
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       LA
Maine           ME
Maryland        MD
Massachusetts   MA
Michigan        MI
Minnesota       MN
Mississippi     MS
Missouri        MO
Montana         MT
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


## Rules

• Input and output are both case sensitive. You many not output e.g. Al for Alabama.
• You may assume the input is one of the 50 state names shown above.
• You may not access the internet or use built-in state data (looking at you, Mathematica).

Separate lists of inputs and outputs can be found in this snippet (please don't run it, it's just for compressing the post):

Alabama
Arizona
Arkansas
California
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
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

(Non-scoring) Brownie points if you can also take District of Columbia as input and produce DC, Virgin Islands, etc etc.

## Scoring

This is , so the shortest code in bytes in each language wins.

(Originally proposed by ETHProductions)

• For those curious to know Mathematica's approach: Entity[a="AdministrativeDivision",{#,"UnitedStates"}]@EntityProperty[a,"StateAbbreviation"]& – DavidC May 26 '17 at 7:05
• @BetaDecay Questions that are closed as off-topic are not useful dupe targets. – Mego May 26 '17 at 7:08
• @DavidC You can save 20 bytes: Entity["AdministrativeDivision",{#,"UnitedStates"}]@"StateAbbreviation"& :) – ngenisis May 26 '17 at 18:28
• Offer extra credit for including the other 12 two-character codes in the complete official list of US postal abbreviations: AA (ARMED FORCES AMERICAS), AE (ARMED FORCES EUROPE), AP (ARMED FORCES PACIFIC), AS (AMERICAN SAMOA), DC (DISTRICT OF COLUMBIA), FM (FEDERATED STATES OF MICRONESIA), GU (GUAM), MH (MARSHALL ISLANDS), MP (NORTHERN MARIANA ISLANDS), PR (PUERTO RICO), PW (PALAU), VI (VIRGIN ISLANDS). – joe snyder May 27 '17 at 15:47
• Yeah this is not a dupe. – Christopher May 27 '17 at 18:27

## Javascript, 124 117 bytes

(saved 7 bytes thanks to 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()


Explanation:

• The regexp finds a match with the first and last letters the two letters of the abbreviation
• First part matches states with more than two words (including District of Columbia)
• Second part matches Alaska and Arizona
• Third part matches Massachusets, Mississippi and Missouri
• Fourth part matches Michigan, Minnesota and Montana
• Sixth part matches all remaining states abbreviated to their first two letters, with a special case to exclude Iowa
• Seventh part matches all remaining states abbreviated to their first and third letters
• Eighth part matches everything else, which are abbreviated to their first and last letters
• Then it is just a case of stripping of those letters and capitalising
• Also matches Puerto Rico and American Samoa, but not Guam, Marianas islands or US Virgin Islands
• Wow, this is great! +1! – NoOneIsHere May 26 '17 at 15:00
• Nice! Some more opportunities: the initial [A-Z] is not necessary since the input is known to be valid. The Iowa special case can be shortened to [AFIOUW][^o] to exclude it, leaving it for the final .+. – hvd May 26 '17 at 15:23
• Your regex machinery is so efficient compared to mine...wish there was a way to make it work with my shorter regex. But they're constructed on such different principles. – Steve Bennett May 26 '17 at 15:36
• Well there are quite a few that are weird in their own ways. There's a nice collection that match both the "first and last" and "first two" rules (Colorado, Delaware, California...), but then Mississippi (MS) ruins it. – Steve Bennett May 26 '17 at 16:26
• 101: s=>s[0]+/.+[A-Zz]|Nev?|.*sk|M.ss.s?|M[io]n?t?|[AFIOUW][^o]|Te.|.+/.exec(s)[0].slice(-1).toUpperCase() Can we get to 100? :) – Steve Bennett May 27 '17 at 23:12

## Javascript, 137135134132113110108101999493 92 bytes

This is based on HP Williams solution, with some improvements outside the regex, and a couple of tweaks within it.

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


Commentary for the regex:

.*( .|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


Pointless alternative regex (same length):

/...(a$|z|s.s?|.* .)|M[i-t]+|T..|[AFINOUW].v?|.*/  ## History ### 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)


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)


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


# PHP>=7.1, 113 Bytes

<?=($a=$argn)[0],ucfirst(preg_match('#[vxz]| .|owa|lask|[CGHKLPV].*|ssi?.|n(n|t|[de]$)#',$a,$t)?$t[0][-1]:$a[1]);  Online Version The strikes are match through a earlier beginning match before ([vxz]) matches Arizona, Nevada, New Mexico, Pennsylvania, Texas, (.) (one space before) matches New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Rhode Island, South Carolina, South Dakota, West Virginia [CGHKLPV].*(.) matches California, Colorado, Connecticut, Georgia, Hawaii, Kansas, Kentucky, Louisiana, New Hampshire, North Carolina, Pennsylvania, South Carolina, Vermont, Virginia, West Virginia ow(a) match Iowa las(k) match Alaska ssi?(.) matches Massachusetts, Mississippi, Missouri, Tennessee n(n|t|[de]$) matches Connecticut, Kentucky, Maine, Maryland, Minnesota, Montana, Pennsylvania, Rhode Island, Tennessee, Vermont

No match for these states so we take the first two letters Alabama, Arkansas, Delaware, Florida, Idaho, Illinois, Indiana, Michigan, Nebraska, Ohio, Oklahoma, Oregon, Utah, Washington, Wisconsin, Wyoming

First time that I am use this Regex Subpatter ?| with allows to store the backreferences in one.

## Support the District of Columbia

Replace (.) with ([^o]) +3 Bytes

Try it online!

# PHP, 150 Bytes

<?=($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]);  Try it online! Testcases • Isn't n|t| a byte shorter than [nt]|? – Neil May 27 '17 at 18:18 • @Neil Yes it is. I have not realize it. Thank You – Jörg Hülsermann May 27 '17 at 18:55 PHP, 887 854 bytes <?=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]];


Try it online!

First timer, hooray!

• This way a little golfed In the Array are the values with space or where the second letter is correct removed. And $argv[1] is replaced with $argn sandbox.onlinephpfunctions.com/code/… – Jörg Hülsermann May 26 '17 at 20:20
• @JörgHülsermann thanks a lot! I really enjoy your answers here on codegolf in php! – Ivanka Todorova May 26 '17 at 20:22
• I am only a little light against other people here. The learning effort is good if someone finds an improvement. I hope that you answer more questions in the future – Jörg Hülsermann May 26 '17 at 20:31

# C, 945937718711660 616 bytes

Saved 219 bytes thanks to ASCII-only.

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);}


Newline unnecessary, only for display purposes. Takes the state as input. Try it online!

How it works:

• struct{int*a,b;}m[]=... declares a map m with two values - a four-byte string and one character. This is used in the comparison loop, which compares the second through fifth indexes with char*a in the map.
• gets(b) reads a string b. This will be the state to abbreviate.
• putchar(*b) prints the first character of that string, since each abbreviation starts with the first letter of the state.
• for(;m[i].a;i++) loops through each value of the map. (This might be able to be shortened.)
• if(!strncmp(m[i].a,b+1,4)) compares the current map value to the second through fifth characters of b (the state to abbreviate). This is because the only differences are in the first five characters, but we've already printed the first character.
• puts(&m[i].b); prints the second letter of the abbreviation (if the state name matches with the current map value), and a newline.
• This seems to produce wrong output for the North*/South* states. – Felix Dombek May 26 '17 at 15:43

# C, 148 141 bytes

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) considers the second through fifth character of the input to be an integer; that integer is then hashed into 0-56 using the hash i%663694%57. The hashed value is then looked up in a vector of offsets which represent the location of the second letter of the abbreviation. I chose those particular four bytes because (1) Missouri and Mississippi first differ in the fifth character and (2) some states have only four characters In C you can use the the NUL terminator byte, but nothing beyond that is reliable. (This hashes both Norths to the same value, as well as both Souths. But that doesn't matter because the associated offset is 6 for all of these.)

As it happens, that particular hash yields the correct position for the second letters of the abbreviations of District of Columbia, Puerto Rico and "Virgin Islands" (typed that way, not as "US Virgin Islands", because the algorithm insists that the first character of the abbreviation be the first character of the name).

The constants 663694 and 57 were found with an automated test; 57 was the smallest hash range I found. (The first version used 380085 and 63, but when I extended the test range I found the new one.) It seems that a slightly smaller hash exists if a code is added for "use the last character in the name"; unfortunately, C syntax for selecting the last character is too wordy to make that helpful.

There are only 8 different offsets, so they could have been stored in a 171-bit (3*57) lookup table with three bits per entry. But I couldn't think of a way to insert those bits efficiently into the program. Hex-encoding would require about one character per four bits, plus the 0x prefixes. I couldn't do better than 151 bytes, which is much longer than the string version. If the 171 bits could somehow be inserted as raw octets, they would occupy 22 bytes, so there might be a solution, but reading a file is clunky.

# Actually, 181 bytes

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


This solution expects input as a quoted string.

Try it online!

## Explanation

This solution utilizes the same hashing strategy as my Python 3 solution. For brevity, I am going to omit the explanation of how the hash is computed and why it was chosen (go read the other answer if you want that bit).

Also for brevity, I'm going to be leaving out the contents of the very long strings, since otherwise the explanation would be unreadable.

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
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


# Python 3, 230 bytes

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]  Try it online! Input is expected as a bytes object (a byte string, rather than a Unicode string). Thanks to Johnathon Allan for an absurd amount of bytes ## Explanation Each state name is hashed to an integer a by applying the hash a = sum(o*5**i) % 236 (where o is a character's ASCII ordinal and i is its index in the string, counting back from the end). The modulus 236 was chosen because it is the smallest modulus that causes all hash values to be distinct for the 50 US state names. These hashes are then mapped to the state abbreviations, and the resulting dictionary (compressed using string substitution) is used to look up the abbreviation given a state name (hashing it to get the appropiate key). • Save 179 bytes with 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] – Jonathan Allan May 26 '17 at 10:58 • ...and another 51 on top of that with lambda s:chr(s[0])+'IA%%L!NOI!M%!E.N!Y.XR.ZD.I!.DDA.D%!.HA!LJ%.N%T.I%!C!T!.HAAT.A!.VL.V%CE%%AEK%.T!.Y.A!.R.YO.S%!.K!.S'.replace('%','$$').replace('$','!!').replace('!','..')[sum(c*5**i for i,c in enumerate(s[::-1]))%236-5] – Jonathan Allan May 26 '17 at 11:46 • I'm surprised that counting backwards costs fewer bytes than a hash function that counts forwards -- but I can't find one with a little playing – Chris H May 26 '17 at 15:41 • @ChrisH I thought I found one, but the compressed string is more expensive. – Mego May 26 '17 at 16:14 # Ruby, 106 103 bytes ->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}


If the input contains a space, the second output letter is the one after the space. Else...

Hash the sum of all characters in the input to obtain a character whose index in the magic string indicates the index of the second output letter in the input string, according to the formula j>8?j/4:-1 (-1 means the end.). If the hash gives a character that is not in the magic string, second letter is second letter of input.

As an explanation of the magic string, the hash characters and the letter indexes they encode are below. Note that Delaware appears even though the second letter would do - this is because its hash code clashes with Kentucky. Fortunately the last letter of Delaware is the same as the second.

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


Ungolfed in test program

a="Alabama
Arizona
Arkansas
California
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
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]]}


# ///, 619 608 bytes

/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/


Try it online!

Since there is no other way of taking input in ///, it goes at the end of the program. Just append the desired input to the program.

Saved 11 bytes by making more replacements, as recommended by @SteveBennett

• There's probably some patterns you can replace multiple times at once, like "New " and "akota". Annoying that you can't do much smarter like removing sections of state names, because converting the remaining character to uppercase is so expensive... – Steve Bennett May 27 '17 at 5:48
• @SteveBennett Edited, thanks! – Comrade SparklePony May 27 '17 at 12:13

# Python 2, 131 125 bytes

lambda s:s[0]+'CLLKARADEZVAK.T..DETTH.NSAHY...ID.D..O..Y.IRE.X..NALINC.VJM.SY.T..AAOI'[int(s[0]+s[-2:],36)%386%334%181%98%70]


Try it online!

# TAESGL, 386 bytes

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


Interpreter

Very simple compression of the state names, added into an array with the abbreviations.

# Japt, 383 bytes

The compression of the first string may be improvable by experimenting with the order of the letters.

g +lkzÇUaidlnyaÀÍ¥evhjmycdhkÎödnxttaaviygalabaµ
Ã2ka
iza
kÂ6s
Öâfnia
åªv
Ü.Ø
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
vÚ
virgia
Øgn
ØÙ virgia
æÈ;n
wyÇg·bUv) u


Try it online

## Mathematica, 138140 134 Bytes

+2 bytes - found a mistake (needed array offset of 1 not 0)

-6 bytes - found a better hash

#~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}&

Similar to others it takes the name and takes the first letter. Then it applies the default Mathematica hash then applies two modulus to it "Hash@#~Mod~89866736~Mod~73" to get a unique number for each state. This value is then looked up in a string to generate the second letter.

Can probably be golfed more but the search space is huge for Mathematica to find. Duplicated second letters weren't considered in the hash search. _ characters represent wasted values in the string. In theory you could get the string down to only 19 characters but finding the custom hash to produce that would be a nightmare.

# Perl 5, 150 148 bytes (147 + 1)

This is by no means optimal, but it does its job. Needs -n command line flag.

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"


# Python 2, 152 bytes

lambda s:s[0]+'.NY.SDS...O.DT..RT.AAYJZE.K.I.X.TI.EL.CMI..E.NA..L....TH.......O....DAAC..VNH.YAI.RVDA..L....A'[int(s.replace(' ','')[1:],36)%358%235%95]
`

Try it online!