Abbrevia lo stato americano!


50

Dato uno dei 50 nomi di stati USA a sinistra come input, genera il suo codice postale di due lettere come mostrato a destra:

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

Regole

  • Input e output fanno distinzione tra maiuscole e minuscole. Molti non producono ad esempio Alper Alabama.
  • Si può presumere che l'ingresso sia uno dei 50 nomi di stato mostrati sopra.
  • Non puoi accedere a Internet o utilizzare i dati di stato incorporati (guardandoti, Mathematica).

Elenco separato di input e output può essere trovato in questo frammento (per favore non eseguirlo, è solo per comprimere il post):

(Senza punteggio) Punti Brownie se puoi anche prendere District of Columbiacome input e produrre DC, Isole Vergini, ecc.

punteggio

Questo è , quindi vince il codice più breve in byte in ogni lingua .

(Originariamente proposto da ETHProductions)


11
Per i curiosi di conoscere l'approccio di Mathematica:Entity[a="AdministrativeDivision",{#,"UnitedStates"}]@EntityProperty[a,"StateAbbreviation"]&
DavidC

12
@BetaDecay Le domande chiuse come fuori tema non sono utili destinazioni dupe.
Mego

7
@DavidC Puoi salvare 20byte: Entity["AdministrativeDivision",{#,"UnitedStates"}]@"StateAbbreviation"&:)
ngenisis,

2
Offri credito extra per l'inclusione degli altri 12 codici a due caratteri nell'elenco ufficiale completo delle abbreviazioni postali statunitensi: AA (ARMED FORCES AMERICAS), AE (ARMED FORCES EUROPE), AP (ARMED FORCES PACIFIC), AS (AMERICAN SAMOA), DC (DISTRETTO DI COLUMBIA), FM (STATI FEDERATI DI MICRONESIA), GU (GUAM), MH (ISOLE MARSHALL), MP (ISOLE MARIANA SETTENTRIONALI), PR (PUERTO RICO), PW (PALAU), VI (ISOLE VERGINI).
joe snyder,

2
Sì, questo non è un inganno.
Christopher,

Risposte:


25

Javascript, 124 117 byte

(salvato 7 byte grazie a 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()

Spiegazione:

  • Il regexp trova una corrispondenza con la prima e l'ultima lettera delle due lettere dell'abbreviazione
  • La prima parte corrisponde agli stati con più di due parole (incluso il Distretto di Columbia)
  • La seconda parte corrisponde ad Alaska e Arizona
  • La terza parte corrisponde a Massachusets, Mississippi e Missouri
  • La quarta parte corrisponde a Michigan, Minnesota e Montana
  • Quinta parte: Nebraska e Nevada
  • La sesta parte corrisponde a tutti gli stati rimanenti abbreviati nelle loro prime due lettere, con un caso speciale per escludere lo Iowa
  • La settima parte corrisponde a tutti gli altri stati abbreviati alla loro prima e terza lettera
  • L'ottava parte corrisponde a tutto il resto, che sono abbreviati nella loro prima e ultima lettera
  • Quindi si tratta solo di eliminare le lettere e scrivere in maiuscolo
  • Abbina anche il Porto Rico e le Samoa americane, ma non Guam, le isole Marianas o le Isole Vergini americane

Wow, è fantastico! +1!
NoOneIsHere

3
Bello! Qualche opportunità in più: l'iniziale [A-Z]non è necessaria poiché è noto che l'input è valido. Il caso speciale dell'Iowa può essere abbreviato [AFIOUW][^o]per escluderlo, lasciandolo per la finale .+.
hvd,

1
Il tuo macchinario regex è così efficiente rispetto al mio ... vorrei che ci fosse un modo per farlo funzionare con il mio regex più corto. Ma sono costruiti su principi così diversi.
Steve Bennett,

1
Bene, ce ne sono alcuni che sono strani a modo loro. C'è una bella collezione che corrisponde alle regole "primo e ultimo" e "prime due" (Colorado, Delaware, California ...), ma poi il Mississippi (MS) lo rovina.
Steve Bennett,

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()possiamo arrivare a 100? :)
Steve Bennett,

22

Javascript, 137 135 134 132 113 110 108 101 99 94 93 92 byte

Questo si basa sulla soluzione HP Williams, con alcuni miglioramenti al di fuori della regex e un paio di modifiche al suo interno.

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

(Interruzioni di riga solo per leggibilità)

Commento per la 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

Regex alternativo inutile (stessa lunghezza):

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

Storia

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

Questo è semplicemente folle, vorrei poter votare di nuovo.
ETHproductions

Non guardare adesso! 99!
Steve Bennett,

94. Totalmente pazzo. Ho scoperto questa ottimizzazione ( ...s.s?cattura Mississippi, Missouri, Massachussetts e Alaska) per caso. In realtà stavo per spostare il .*skframmento da qualche altra parte, e i test sono semplicemente passati e passati, mentre il frammento non era presente da nessuna parte. Il più semplice guadagno di 5 personaggi di sempre!
Steve Bennett,

Wow, e mi sono appena reso conto che ...s.s?sta anche inavvertitamente abbinando il Kansas e, per miracolo, sta ancora dando il giusto risultato.
Steve Bennett,

E un altro personaggio con M[onti]+. Così strano: se lo stato inizia con M, la seconda lettera è l'ultima in una sequenza di almeno una o, n, t o i. Un modo molto strano di catturare Michican, Minnesota o Montana.
Steve Bennett,

20

JavaScript (ES6), 156 136 byte

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]

dimostrazione


1
Questo bruteforce è ottimale usando questo metodo?
ASCII

2
@ Solo ASCII Questo è rinforzato su intervalli arbitrali, quindi è garantito solo per essere ottimale X MOD[50-1000] MOD[50-1000] MOD[50-100]. Ma è .slice(1)stato un errore. Attualmente in esecuzione di nuovo sull'intera stringa.
Arnauld,

2
Potresti spiegare a un principiante cosa fa?
Hankrecords,

1
@Hankrecords Certo, lo farà. (Ma sono su un treno con accesso limitato a Internet in questo momento.)
Arnauld,

1
ora il mio ha 135 anni!
Steve Bennett,

17

Gelatina , 75 byte

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

Provalo online!

... o vedere una suite di test - Notare che è stato necessario apportare una piccola modifica per eseguire l'intero programma per più ingressi in una volta (ho scambiato l'atomo di ingresso del programma ³, per un richiamo dal registro ®, uno e impostato il registro a ogni nome di stato a sua volta).

Come?

Calcola l'indice da utilizzare per il secondo carattere del codice postale, lo aggiunge al primo carattere e mette in maiuscolo il risultato.

Prima trova l'indice di uno spazio (o 0 se non trovato);

Altrimenti controlla se è l'Alaska o il Missouri (producendo 5 per ko o);

Altrimenti trova l'indice dello stato di input nell'elenco Arizona Minnesota Mississippi Nevada Montana Texas Tennessee(o 0 se non trovato) - in tal caso prende quell'indice mod 2 più 3 (per z n s v t x n);

Altrimenti converte la stringa in ordinali, converte quella dalla base 256, trova il resto di quello dopo aver diviso per 29487, trova il resto dopo aver diviso per 14 e usa quello per indicizzare nella rappresentazione binaria di 9620 e raddoppia il risultato - producendo 0 per gli stati che usano la loro lettera finale e 2 per quelli che usano la loro seconda lettera.

Tutti tranne il primo caso vengono incrementati e il valore risultante viene diminuito (aumentando l'indice di spazio trovato di uno).

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
Questa è la gelatina più lunga che abbia mai visto =)
caird coinheringaahing

11

Python 2 , 191 byte

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]

Provalo online!

Utilizza una semplice funzione hash per trovare il secondo carattere dell'abbreviazione.


11

Python 2, 94 90 byte

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

Provalo online

(Solo Python 2 perché gli hash di Python 3 non sono stabili e inoltre non puoi hash una stringa senza trasformarla in byte.)

Funziona con tutti i 50 stati, oltre a un distretto bonus di Columbia e Puerto Rico.

Sarebbe possibile salvare un byte scrivendo il numero in base-36: int("5clu7x0aixb0pelmpugv5iiibphrpf",36). Sto aspettando di vedere se riesco a pensare a una soluzione più creativa.

Aggiornare:

Dato che nell'hash ci sono 12 posizioni di cifre non utilizzate, ci sono 2 36 possibili numeri che funzioneranno. Sembrava ragionevole credere che uno di loro avrebbe avuto un fattore primo con un grande esponente. Per ogni dato primo ed esponente, trovare un valore è abbastanza veloce; Sono riuscito a trovarne uno con un fattore di 19 9 , riducendo la dimensione dell'espressione necessaria per rappresentare il numero di quattro byte.

Questa è sostanzialmente la stessa procedura della mia risposta in C ma usando Python. Dato che la funzione hash di base è diversa, ho dovuto trovare una diversa funzione di riduzione, che risulta essere mod 52 anziché mod 54. Ma i maggiori risparmi su C derivano dalla possibilità di usare i bignum per codificare il vettore, e ovviamente il fatto che lo standard per Python sembra essere che è ok usare un lambda letterale invece di un programma completo.


9

Retina , 113 81 80 77 70 68 byte

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

T`l`L

Provalo online! Include tutti i 51 casi di test. Ho salvato 32 byte appropriandosi della regex di @ JörgHülsermann che trova la seconda lettera (con una modifica per supportare DC; modifica: salvato 1 byte grazie a @ JörgHülsermann). Salvato 3 byte passando alla regex di @ SteveBennett dal suo commento alla risposta di @ HPWilliam. Salvato 7 9 byte grazie ancora a @SteveBennett. Le altre lettere vengono quindi eliminate e la stringa maiuscola.


Molto bello, non avrei mai pensato di poter ottenere un set di stringhe completamente rimovibili.
Colsw,

@ConnorLSW è estato il più problematico, davvero.
Neil,

@ JörgHülsermann Grazie per il favore di ritorno!
Neil,

@ JörgHülsermann Oh, allora potrò salvare un altro byte?
Neil,

1
Attendere, Indiana non diventano ID. Probabilmente puoi risolverlo semplicemente aggiungendo $ dopo il d. (Potresti voler usare il test automatico - ho uno script che controlla costantemente tutti i 50 casi.)
Steve Bennett,

8

PHP> = 7.1, 113 byte

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

Versione online

Gli strike sono abbinati a una partita di inizio precedente prima

([vxz])partite Arizona, Nevada, New Mexico, Pennsylvania, Texas,

(.) (uno spazio prima) corrisponde a New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Rhode Island, South Carolina, South Dakota, West Virginia

[CGHKLPV].*(.)partite California, Colorado, Connecticut, Georgia, Hawaii, Kansas, Kentucky, Louisiana, New Hampshire , Carolina del Nord, Pennsylvania, Carolina del Sud , Vermont, Virginia, Virginia Occidentale

ow(a) partita Iowa

las(k) partita Alaska

ssi?(.)partite Massachusetts, Mississippi, Missouri, Tennessee

n(n|t|[de]$)partite Connecticut, Kentucky, Maine, Maryland, Minnesota, Montana, Pennsylvania, Rhode Island, Tennessee, Vermont

Nessuna corrispondenza per questi stati, quindi prendiamo le prime due lettere Alabama, Arkansas, Delaware, Florida, Idaho, Illinois, Indiana, Michigan, Nebraska, Ohio, Oklahoma, Oregon, Utah, Washington, Wisconsin, Wyoming

La prima volta che sto usando questo Subpatter Regex ?| con mi permette di archiviare i backreferences in uno.

Sostieni il distretto di Columbia

Sostituisci (.)con ([^o])+3 byte

Provalo online!

PHP, 150 byte

<?=($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]);

Provalo online! Casi test


3
n|t|Un byte non è più corto di [nt]|?
Neil,

@Neil Sì, lo è. Non me ne sono reso conto. Grazie
Jörg Hülsermann,

7

PHP, 887 854 byte

<?=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]];

Provalo online!

Primo timer, evviva!


1
In questo modo un po 'golfato nell'array sono i valori con spazio o in cui la seconda lettera è stata rimossa correttamente. E $argv[1]viene sostituito con $argn sandbox.onlinephpfunctions.com/code/…
Jörg Hülsermann

@ JörgHülsermann grazie mille! Mi piacciono molto le tue risposte qui su codegolf in php!
Ivanka Todorova,

Sono solo una piccola luce contro le altre persone qui. Lo sforzo di apprendimento è buono se qualcuno trova un miglioramento. Spero che risponderai ad altre domande in futuro
Jörg Hülsermann,

7

C, 945 937 718 711 660 616 byte

219 byte salvati grazie solo a 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);}

Newline non necessario, solo a scopo di visualizzazione. Prende lo stato come input. Provalo online!

Come funziona:

  • struct{int*a,b;}m[]=...dichiara una mappa mcon due valori: una stringa di quattro byte e un carattere. Questo viene utilizzato nel ciclo di confronto, che confronta gli indici dal secondo al quinto con char*anella mappa.
  • gets(b)legge una stringa b. Questo sarà lo stato da abbreviare.
  • putchar(*b) stampa il primo carattere di quella stringa, poiché ogni abbreviazione inizia con la prima lettera dello stato.
  • for(;m[i].a;i++)scorre attraverso ogni valore della mappa. (Potrebbe essere possibile accorciare questo.)
  • if(!strncmp(m[i].a,b+1,4))confronta l'attuale valore della mappa con il secondo al quinto carattere di b(lo stato da abbreviare). Questo perché le uniche differenze sono nei primi cinque caratteri, ma abbiamo già stampato il primo carattere.
  • puts(&m[i].b); stampa la seconda lettera dell'abbreviazione (se il nome dello stato corrisponde al valore corrente della mappa) e una nuova riga.

Ciò sembra produrre un output errato per gli stati Nord * / Sud *.
Felix Dombek,

6

C, 148 141 byte

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)considera il secondo al quinto carattere dell'input come un numero intero; quell'intero viene quindi hash in 0-56 usando l'hash i%663694%57. Il valore di hash viene quindi cercato in un vettore di offset che rappresentano la posizione della seconda lettera dell'abbreviazione. Ho scelto quei quattro byte particolari perché (1) Missouri e Mississippi differiscono per primi nel quinto carattere e (2) alcuni stati hanno solo quattro caratteri In C è possibile utilizzare il byte terminatore NUL, ma nulla oltre a ciò è affidabile. (Questo ha entrambi i Nord allo stesso valore, così come entrambi i Sud. Ma non importa perché l'offset associato è 6 per tutti questi.)

In effetti, quel particolare hash fornisce la posizione corretta per le seconde lettere delle abbreviazioni di District of Columbia, Puerto Rico e "Isole Vergini" (digitate in questo modo, non come "Isole Vergini americane", perché l'algoritmo insiste sul fatto che il primo carattere dell'abbreviazione essere il primo carattere del nome).

Le costanti 663694 e 57 sono state trovate con un test automatizzato; 57 è stata la gamma di hash più piccola che ho trovato. (La prima versione utilizzava 380085 e 63, ma quando ho esteso l'intervallo di test ho trovato quella nuova.) Sembra che esista un hash leggermente più piccolo se viene aggiunto un codice per "usa l'ultimo carattere nel nome"; sfortunatamente, la sintassi C per selezionare l'ultimo carattere è troppo prolissa per renderlo utile.

Esistono solo 8 offset diversi, quindi potrebbero essere stati memorizzati in una tabella di ricerca a 171 bit (3 * 57) con tre bit per voce. Ma non riuscivo a pensare a un modo per inserire quei bit in modo efficiente nel programma. La codifica esadecimale richiederebbe circa un carattere per quattro bit, più i 0xprefissi. Non ho potuto fare meglio di 151 byte, che è molto più lungo della versione stringa. Se i 171 bit potessero in qualche modo essere inseriti come ottetti grezzi, occuperebbero 22 byte, quindi potrebbe esserci una soluzione, ma la lettura di un file è scomoda.


4

In realtà , 181 byte

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

Questa soluzione prevede input come stringa tra virgolette.

Provalo online!

Spiegazione

Questa soluzione utilizza la stessa strategia di hashing della mia soluzione Python 3 . Per brevità, ometterò la spiegazione di come viene calcolato l'hash e perché è stato scelto (vai a leggere l'altra risposta se vuoi quel bit).

Anche per brevità, tralascerò il contenuto delle stringhe molto lunghe, poiché altrimenti la spiegazione sarebbe illeggibile.

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 byte

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]

Provalo online!

L'input è previsto come oggetto byte (una stringa di byte anziché una stringa Unicode).

Grazie a Johnathon Allan per un'assurda quantità di byte

Spiegazione

Ogni nome di stato viene sottoposto a hash su un numero intero aapplicando l'hash a = sum(o*5**i) % 236(dove si otrova l'ordinale ASCII di un personaggio ed iè il suo indice nella stringa, contando alla fine). Il modulo è 236stato scelto perché è il modulo più piccolo che determina la distinzione di tutti i valori di hash per i 50 nomi di stati USA. Questi hash vengono quindi associati alle abbreviazioni di stato e il dizionario risultante (compresso mediante sostituzione di stringa) viene utilizzato per cercare l'abbreviazione a cui viene assegnato un nome di stato (hashing per ottenere la chiave appropriata).


Salva 179 byte conlambda 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

... e un altro 51 per di più conlambda 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]
Jonathan Allan

Sono sorpreso che il conteggio all'indietro costa meno byte di una funzione di hash che conta in avanti - ma non riesco a trovarne uno con un po 'di gioco
Chris H,

1
@ChrisH Pensavo di averne trovato uno, ma la stringa compressa è più costosa.
Mego

2

Rubino, 106 103 byte

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

Se l'input contiene uno spazio, la seconda lettera di output è quella dopo lo spazio. Altro...

Hash la somma di tutti i caratteri nell'input per ottenere un carattere il cui indice nella stringa magica indica l'indice della seconda lettera di output nella stringa di input, secondo la formula j>8?j/4:-1(-1 significa la fine). Se l'hash dà un carattere che non è nella stringa magica, la seconda lettera è la seconda lettera di input.

Come spiegazione della stringa magica, i caratteri hash e gli indici delle lettere che codificano sono di seguito. Nota che Delaware appare anche se la seconda lettera lo farebbe - questo perché il suo codice hash si scontra con il Kentucky. Fortunatamente l'ultima lettera del Delaware è la stessa della seconda.

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 

Non registrato nel programma di test

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 byte

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

Provalo online!

Dal momento che non esiste un altro modo per inserire input in ///, va alla fine del programma. Basta aggiungere l'input desiderato al programma.

Salvato 11 byte apportando più sostituzioni, come raccomandato da @SteveBennett


Probabilmente ci sono alcuni schemi che puoi sostituire più volte contemporaneamente, come "Nuovo" e "Akota". Fastidioso che non si possa fare molto più intelligenti come rimuovere sezioni di nomi di stato, perché convertire il carattere rimanente in maiuscolo è così costoso ...
Steve Bennett,

@SteveBennett Modificato, grazie!
Compagno SparklePony,

2

Python 2 , 131 125 byte

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]

Provalo online!


1

TAESGL , 386 byte

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

Interprete

Compressione molto semplice dei nomi degli stati, aggiunta in un array con le abbreviazioni.


1

Japt, 383 byte

La compressione della prima stringa può essere migliorabile sperimentando l'ordine delle lettere.

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

Provalo online


1

Mathematica, 138 140 134 byte

+2 byte - trovato un errore (offset matrice necessario di 1 non 0)

-6 byte - trovato un hash migliore

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

Simile ad altri prende il nome e prende la prima lettera. Quindi applica l'hash Mathematica predefinito quindi applica due moduli " Hash@#~Mod~89866736~Mod~73" per ottenere un numero univoco per ogni stato. Questo valore viene quindi cercato in una stringa per generare la seconda lettera.

Probabilmente si può giocare a golf di più, ma lo spazio di ricerca è enorme per Mathematica da trovare. Le seconde lettere duplicate non sono state considerate nella ricerca hash. _i caratteri rappresentano valori sprecati nella stringa. In teoria potresti ridurre la stringa a soli 19 caratteri, ma trovare l'hash su misura da produrre sarebbe un incubo.


1

Perl 5, 150 148 byte (147 + 1)

Questo non è affatto ottimale, ma fa il suo lavoro. Richiede -nflag della riga di comando.

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"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.