Golfe Prático - Estados dos EUA [fechado]

11

Minha família tem um negócio de comércio eletrônico. Em nosso próprio site, forçamos as pessoas a escolher seu estado em um menu suspenso ao inserir seu endereço, mas através de outros canais que usamos, os clientes podem inserir o que quiserem na caixa.

Minha mãe adora os modelos de fatura que fiz para ela, que são gerados automaticamente. Mas, por serem tão bonitas e equilibradas, ela não consegue suportar quando as pessoas ESCREVEM os nomes de seus estados, ou pior, escrevem algo como "Nova Jersey". Ela diz que isso estraga o visual.

Meu pai gosta que o código seja leve. Portanto, em vez de usar um bloco de caixas de chaves, ele deseja uma solução mais enxuta.

Portanto, o desafio é criar uma função curta que aceite as entradas possíveis e retorne uma abreviação de duas letras (maiúscula, para mamãe). Vamos fazer uma suposição (defeituosa) de que nossos usuários podem soletrar e sempre colocar um espaço no nome (quando necessário) ou passar a abreviação correta. O escopo são os 50 estados dos EUA.

  • Nova york
  • Nova york
  • Nova Iorque
  • Nova Iorque

são todas entradas aceitáveis ​​para Nova York e devem produzir NY.

Se algo como New Yrok for passado, a função poderá retornar o valor original.

Você pode usar qualquer idioma comum. Este é um concurso de popularidade e, portanto, o vencedor com mais votos no final de uma semana. Suponho que isso favorecerá a novidade e a utilidade.

EDIT: A descrição é uma história, mas eu estava trabalhando em um projeto semelhante e pensei que deveria haver uma maneira mais interessante de fazê-lo. Posso fazer o projeto pessoalmente (já fiz), mas achei que esse era um bom lugar para um desafio mais interessante. Por "Qualquer linguagem comum", eu estava excluindo linguagens / bibliotecas personalizadas projetadas para esse desafio - estava tentando procurar métodos novos, em vez de ajudar o código gratuitamente. Eu acho que todo mundo já fez isso em algum momento, mas seria divertido fazê-lo de uma maneira incomum. Acho que os projetos mais interessantes são aqueles em que você lida com as tarefas diárias de maneiras novas e interessantes - é por isso que esse é um concurso de popularidade e não de golfe.

Josiah
fonte
14
Não sei por que esse é um concurso de popularidade, e não um código de golfe (especialmente porque o nome inclui 'golfe' e seu pai favorece o código curto).
Geobits
5
@Claudiu É verdade, mas este site não é destinado para o código de produção ...
Geobits
3
@ Claudiu Sinceramente, presumi que isso fosse "bobagem da história" do tipo que geralmente acompanha esses desafios. De qualquer maneira, quando eu disse "este site ...", quis dizer PP&CG, pois a maioria dos códigos aqui não se destina explicitamente ao uso na produção. Honestamente, se ele está olhando para o código real para uso em seu site, seria mais ético para fazê-lo sozinho ou contratar it out;)
Geobits
8
@chilemagic you can use any code... para que o OP reescreva seu site para usar sua solução APL / CJAM / GolfScript? É um desafio baseado em uma história verdadeira. Eu voto
edc65
4
É uma tarefa bastante trivial, por que o OP faria todo o esforço para digitar uma pergunta, quando seria mais fácil apenas codificá-la? De qualquer maneira, eu gostei de tentar.
James Williams

Respostas:

27

Rubi

Pensei que seria interessante extrair as abreviações de estado sem escrever explicitamente nenhum dos nomes ou abreviações. Este não leva em consideração erros ortográficos da entrada, porque não nos importamos com isso aqui no codegolf.SE, rihgt ?

def f(s)
  [
    /(.).* (.)/,              # two words
    /^([CDGHKLPV]).*(.)$/,    # first and last letter
    /^(.).*([ZVX])/,          # unique letter
    /^([NFOUW])(.)/,          # two first letters
    /^(.)([DNR])/,            # unique second letter
    /^(.).*(L|N)\2/,          # double letters
    /^(.).SS(A|O)/,           # double S before the one used
    /^(.).*?[SNW](.)/,        # identified by the letters before them
    /(.)(.)/                  # two first letters

  ].find { |r| r =~ s.upcase }
  $1+$2
end

Demorou um tempo considerável para descobrir padrões inteligentes para combinar com todos os estados. A ordem dos padrões é importante - cada padrão consecutivo se aplica aos estados restantes que não foram correspondidos por um padrão anterior:

Todos os estados com duas palavras neles usam as letras iniciais das duas palavras:

N ew H ampshire, N ew J ersey, N ew M exico, N ew Y ork, N orte C arolina, N orte D Akota, R hode eu sland, S outh C arolina, S outh D Akota, W est V irginia

Todos os estados que começam com qualquer letra em { CDGHKLPV} usam a primeira e a última letra no nome:

C aliforni um , C olorad O , C onnecticu t , D Elawar E , G eorgi um , H awai i , K ANSA s , K entuck y , G ouisian um , P ennsylvani um , V irgini um , V Ermon t

Dos estados restantes, as letras { ZVX} são exclusivas:

A ri z ona, N e v ada, T e x como

Todos os estados restantes que começam com { FNOUW} usam as duas primeiras letras.

Fl Orida, Ne Braska, Oh io, Ok Lahoma, Ou egon, Ut ah, Wa shington, Wi Sconsin, Wy OMing

Então, { DNR} são únicos como segundas letras:

Ar kansas, Em diana, Id aho

Está realmente ficando difícil fazer padrões gerais, mas ...

Apenas três estados restantes usam o dobro Nou L, e a letra dupla é usada na abreviação de estado:

T en n essee, M em n esota, I l l inois

Aou Odepois do duplo S é exclusivo para

M ass a chusetts e M iss o uri

Sempre que { SNW} aparecer antes de outras letras nos nomes de estado restantes, as letras a seguir serão usadas nas abreviações:

Um las k um, H Arylan d , H ain e , M é s issippi, M em t ana, I ow um

Sobraram dois. Eles usam as duas primeiras letras:

Al abama, Mi chigan


Pode-se jogar golfe, é claro:

Ruby 2 - 191 165 154 caracteres

Outros 26 caracteres desligando um pouco as expressões regulares. Além disso, um dos regexes originais acabou sendo redundante!

gets;[/.* (.)/,/^[CDGHKLPV].*(.)$/,/.*([ZVX])/,/^[NFOUW](.)/,/^.([DNR])/,/.*(L|N)\1/,
/.*SS(A|O)/,/.*?[SNW](.)/,/.(.)/].find{|r|$_.upcase=~r}
puts $&[0]+$1
daniero
fonte
"Atualmente, menos de um terço do tamanho da entrada Golfscript!" : P Lembre-se de que o Golfscript não usa Regexes.
Josiah Winslow
E eu mudei o tamanho. : P
Josiah Winslow
1
(@JosiahWinslow e oh, faça isso 3,9575757575 ...: P)
daniero 4/14
6
lol para os peitos regex na explicação de que não precisava sobreviver compressão
masterX244
1
Eu gosto desta resposta, mas não é válida, pois não consegue identificar entradas inválidas (como você diz). Existe até um exemplo específicoIf something like New Yrok is passed in, the function should return the original value.
edc65
4

C #

Eu usei caracteres já nos estados para as abreviações para encurtar a cadeia de estado.

public string GetAbbr(string state)
            {

                var states =
                    new[] {
                        "AlasKa", "ALabama", "AriZona", "ARkansas", "CAlifornia", "COlorado", "ConnecticuT",
                        "DElaware", "FLorida", "GeorgiA", "HawaiI", "IDaho", "ILlinois", "INdiana", "IowA", "KansaS",
                        "KentuckY", "LouisianA", "MainE", "MarylanD", "MAssachusetts", "MIchigan", "MinNnesota",
                        "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", "washington D.C.", "West Virginia", "WIsconsin", "WYoming"
                    };
                var all = states.ToDictionary(st => string.Concat(st.Where(char.IsUpper)));

                var wanted = all.FirstOrDefault(pair => state.ToUpper().Equals(pair.Value.ToUpper()) || state.ToUpper().Equals(pair.Key));

                return wanted.Key ?? state;
            }
Brandon
fonte
1
Solução agradável!
Beta Decay
2

JavaScript (E6)

Aqui o volume está na lista de nomes, usando o truque camelCase para diminuir um pouco. Golfe, 617 bytes.

F=i=>
  "AkAlAzArCaCoCtDeFlGaHiIdIlInIaKsKyLaMeMdMaMiMnMsMoMtNeNvNhNjNmNyNcNdOhOkOrPaRiScSdTnTxUtVtVaWaWvWiWyAlaskaAlabamaArizonaArkansasCaliforniaColoradoConnecticutDelawareFloridaGeorgiaHawaiiIdahoIllinoisIndianaIowaKansasKentuckyLouisianaMaineMarylandMassachusettsMichiganMinnesotaMississippiMissouriMontanaNebraskaNevadaNew hampshireNew jerseyNew mexicoNew yorkNorth carolinaNorth dakotaOhioOklahomaOregonPennsylvaniaRhode islandSouth carolinaSouth dakotaTennesseeTexasUtahVermontVirginiaWashingtonWest virginiaWisconsinWyoming"
  .match(/.[^A-Z]*/g).map((w,q)=>U(w,U(w)==U(i)?p=q%50:p),U=s=>s.toUpperCase(),p=-1)[p]||i
edc65
fonte
0

Pitão

Decidiu fazer isso como um desafio ao código-golfe. Você baixou para 906 713 694 caracteres com a ajuda de daniero e hsl:

s='AK,AL,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,ALASKA,ALABAMA,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(",")
x=input().upper()
print(s[s.index(x)%50]if x in s else x)

No entanto, se os módulos forem permitidos (como o módulo us ), eu posso reduzi-lo para 130 caracteres:

import us
i=raw_input()
x=us.states.lookup(i)
print x.abbr if x else i

E se você não tivesse que retornar o valor original quando o estado não existe, eu poderia reduzi-lo para 50 caracteres:

import us
print us.states.lookup(raw_input()).abbr
James Williams
fonte
Você pode salvar aproximadamente 200 caracteres no primeiro, deixando suma string grande e depois dividi-la em vírgulas ( ,); Não há necessidade de todas as aspas simples.
Daniero 03/10
@daniero Não acredito que não pensei nisso! Vai fazer agora.
James Williams
Você pode remover Washington, DC, pois não é um estado americano.
NinjaBearMonkey
@hsl Obrigado. Peguei a lista de uma lista de estados que encontrei on-line, não percebi que Washington DC estava lá.
James Williams
0

bash + sed, 291 bytes

Conversão descarada da solução Ruby da Daniero para sed:

echo $*|tr a-z A-Z|sed -e\
"/\(.\).* \(.\).*/b1;/^\([CDGHKLPV]\).*\(.\)$/b1;/^\(.\).*\([ZVX]\).*/b1;\
/^\([NFOUW]\)\(.\).*/b1;/^\(.\)\([DNR]\).*/b1;/^\(.\).*\([LN]\)[LN].*/b1;\
/^\(.\).*SS\([AO]\).*/b1;/^\(.\).*\([ED])\)$/b1;/^\(.\).*[SNW]\(.\).*/b1;\
/\(.\)\(.\).*/b1;:1 s//\1\2/"
Glenn Randers-Pehrson
fonte
0

Golfscript - 750 653

O volume está nos nomes e abreviações do estado.

{.96>32*-}%.,2>{"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"","/.@?)=}{}if

Explicação:

{        }%                         Map this to every character in the input string:
 .96>32*-                             Subtract 32 from the ASCII value if it's from "a" onwards.
                                      This turns every lowercase letter into an uppercase letter.
           .,2>                     Check if the input length is greater than 2.
               {              }     If it is, they inputted the full name.
                "..."                 Our string is in the form "STATE NAME,STATE ABBREVIATION".
                     ","/             We split the string at every comma to turn it into an array.
                         .@?          Then we see where the input string is in the array...
                            )=        ...then we return the value right next to it.
                               {}   If not, they inputted the abbreviation.
                                      ...do nothing.
                                 if EndIf
                                    (implied) Print the abbreviation
Josiah Winslow
fonte
Desculpe, mas não vejo o objetivo de pegar meu script inteiro e adicionar nada além de alguns bytes de clichê; Simplesmente não traz nada. Mas obrigado pelos créditos, eu acho ... Atenciosamente, "o outro cara".
Daniero 5/10
Desculpe, entrada troll. Eu sei que não é uma entrada real.
Josiah Winslow
Bem, considere-me trollado, então;) #
daniero 6/10
@daniero Ei, pelo menos eu sei que é possível ter expressões regulares no Golfscript! Isso é realmente a única razão pela qual eu fiz isso lol: p
Josias Winslow
0

PHP

Minha tentativa, que não teve tanto sucesso quanto eu esperava, usa o comprimento da string e algum posicionamento específico de caracteres para extrair a abreviação do nome do estado. Provavelmente, é possível uma melhor sequência de eliminação de nomes.

function findAbb ($state) {
    $first = substr($state, 0, 1);
    $last = substr($state, -2,1);
    $state = strtolower($state);
    if (strlen($state) < 4) {
        return strtoupper($state);
    }
    if (strpos($state, ' ')) { //if it's a space, return the first letter of each word.
        $space_index = strpos($state, ' ');
        $state = explode(' ', $state);
        return strtoupper(substr($state[0], 0, 1) . substr($state[1], 0, 1));
    }
    if (startsWith($state, 'io')) { //iowa is annoying, get rid of it.
        return strtoupper($first . $last);
    }
    if (startsWith($state, 'w,i')) { //if it starts with a W, return the first 2.
        return strtoupper(substr($state, 0, 2));
    }
    if (strlen($state) < 7 && strpos($state, 'm')===false) { //matches texas, ohio, and utah.
        return strtoupper($first . substr($state, -4,1));
    }
    if (strlen($state) < 7 && substr($state, 0, 1) > 'j' && substr($state, 0, 1) < 'n') { //matches maine, kansas, and hawaii
        return strtoupper($first . $last);
    }
    if (startsWith($state, 'c,d,k,l,p,v,g,h')) { //some unique states
        return strtoupper($first . $last);
    }
    if (strpos($state, 'sk')) {
        return strtoupper ('ak');
    }
    if (startsWith($state, 'k,l', 1)) {
        return strtoupper(substr($state, 0, 2));
    }
    if (startsWith($state, 'n')) {
        return strtoupper($first . substr($state, 2, 1));
    }
    if (startsWith($state, 'n', 2) || startsWith($state, 'z', 3)) { //montana, tennessee, minnesota, and arizona
        return strtoupper($first . substr($state, 3, 1));
    }
    if (startsWith($state, 'm') && ($last == 's') || ($last == 'n')) {
        return strtoupper(substr($state, 0, 2));
    }
    if (strpos($state,'o')) {
        return strtoupper($first . 'o');
    }
    if (strpos($state,'y')) {
        return strtoupper($first . 'd');
    }
    if (strpos($state,'r')) {
        return strtoupper($first . 'r');
    }
    if (strpos($state,'ss')) {
        return strtoupper($first . 's');
    }

    return $state; //otherwise return the name of the state (it was mispelled).
}

function startsWith ($state, $letters, $index = 0) { //takes a comma separated array and finds contents.
    $letters = split(',',$letters);
    for ($q = 0; $q<count($letters); $q++) {
        if (strpos($state,$letters[$q]) === $index) {
            return true;
        }
    }
    return false;
}

Claro, pode ser jogado golfe. Esta é a minha primeira tentativa de golfe, portanto, o insight é apreciado. (911)

function t($s){$s=u($s);$f=b($s,0,1);$l=b($s,-2,1);
if(strlen($s)<4)return $s;if(strpos($s,' '))$s=split(' ',$s);
return b($s[0],0,1).b($s[1],0,1);
if(w($s,'IO'))return $f.$l;
if(w($s,'W,I'))return b($s,0,2);
if(strlen($s)<7 && strpos($s,'M')===false)return $f.b($s,-4,1);
if(strlen($s)<7 && b($s,0,1)>'I' && b($s,0,1)<'N')return $f.$l;
if(w($s,'C,D,K,L,P,V,G,H'))return $f.$l;if(strpos($s, 'SK'))return 'AK';
if(w($s,'K,L',1))return b($s,0,2);if(w($s,'N'))return $f.b($s,2,1);
if(w($s,'N',2) || w($s,'Z',3))return $f.b($s,3,1);
if(w($s,'M') && ($l=='S') || ($l=='N'))return b($s,0,2);
if(strpos($s,'O'))return $f.'O';
if(strpos($s,'Y'))return $f.'D';if(strpos($s,'R'))return $f.'R';
if(strpos($s,'SS'))return $f.'S';return $s;}function w($s,$l,$i=0){$l=split(',',$l);
for($q=0;$q<count($l);$q++)if(strpos($s,$l[$q])===$i)return 1;return 0;}
function u($z){return strtoupper($z);}
function b($v,$x,$y){return substr($v,$x,$y);}
Josiah
fonte
0

Javascript

Eu sei que isso não é código de golfe, mas eu quero jogar de qualquer maneira. :)

var r=new XMLHttpRequest
r.open("GET","https://gist.githubusercontent.com/mshafrir/2646763/raw/f2a89b57193e71010386a73976df92d32221d7ba/states_hash.json",0)
r.send()
var o=r.responseText,m=prompt(),a=m
o=JSON.parse(o)
for(var i in o)if(o[i].toLowerCase()==m.toLowerCase())a=i
alert(a)

Yay para coisas novas! (Snippets de pilha)

Beta Decay
fonte
3
Essa é uma brecha padrão e as brechas padrão se aplicam sem precisar ser mencionado explicitamente.
Ingo Bürk
@ IngoBürk Eu não acredito que isso se enquadre nas brechas padrão ... Ele está obtendo os dados necessários da Internet da mesma maneira que a leitura de um arquivo.
Beta Decay
2
Então, eval(open('a.txt'))também é válido? Se você usar um arquivo de qualquer tipo, também deverá incluir esse arquivo e seu nome na contagem de caracteres. (Isso não é um código de golfe, portanto, na verdade, não importa de qualquer maneira.)
Maçaneta da porta
@ Doorknob Como você argumenta que isso não é código de golfe, não vejo por que estou recebendo votos negativos ... Não violei nenhuma regra de contras pop.
Beta Decay
2
Não há razão para downvote, é perfeitamente no espírito da questão - favor novidade e utilidade - e divertido
edc65