Practical Golf - Stany Zjednoczone [zamknięty]

11

Moja rodzina ma biznes e-commerce. Na naszej stronie zmuszamy ludzi do wybierania ich stanu z menu rozwijanego po wprowadzeniu adresu, ale za pośrednictwem innych używanych przez nas kanałów klienci mogą wpisać w polu dowolne informacje.

Moja mama uwielbia szablony faktur, które dla niej przygotowałem, które są generowane automatycznie. Ale ponieważ są tak ładne i zrównoważone, nie może tego znieść, gdy ludzie NAPISUJĄ nazwy swoich stanów lub, co gorsza, piszą coś w stylu „nowej koszulki”. Mówi, że to psuje wygląd.

Mój tata lubi, żeby kod był lekki. Więc zamiast używać bloku szafy rozdzielczej, chce lżejszego rozwiązania.

Wyzwanie polega więc na stworzeniu krótkiej funkcji, która przyjmuje możliwe dane wejściowe i zwraca dwuliterowy skrót (wielkie litery dla mamy). Przyjmiemy (błędne) założenie, że nasi użytkownicy mogą przeliterować i zawsze wstawiać spację w nazwie (w razie potrzeby) lub podawać poprawny skrót. Zakres obejmuje 50 stanów USA.

  • Nowy Jork
  • Nowy Jork
  • NY
  • ny

są wszystkie dopuszczalne dane wejściowe dla Nowego Jorku i powinny dać wynik NY.

Jeśli zostanie przekazane coś takiego jak New Yrok, funkcja może zwrócić oryginalną wartość.

Możesz używać dowolnego wspólnego języka. To konkurs popularności, więc wygrywa ten, który pod koniec tygodnia uzyska najwięcej głosów. Zakładam, że sprzyja to nowości i użyteczności.

EDYCJA: Opis jest puchowy, ale pracowałem nad podobnym projektem i pomyślałem, że musi być bardziej interesujący sposób. Mogę samodzielnie wykonać projekt (już to zrobiłem), ale pomyślałem, że to dobre miejsce na bardziej interesujące wyzwanie. Przez „Dowolny wspólny język” wykluczyłem niestandardowe języki / biblioteki przeznaczone do tego wyzwania - starałem się szukać nowych metod, a nie darmowej pomocy przy kodzie. Myślę, że wszyscy kiedyś to zrobili, ale fajnie byłoby to zrobić w niecodzienny sposób. Uważam, że najciekawsze projekty to te, w których podejmujesz codzienne zadania w nowy i interesujący sposób - dlatego jest to konkurs popularności, a nie golf.

Josiah
źródło
14
Nie jestem pewien, dlaczego jest to konkurs popularności zamiast golfa kodowego (zwłaszcza, że ​​nazwa zawiera „golf”, a twój tata preferuje krótki kod).
Geobits
5
@Claudiu To prawda, ale ta strona nie jest przeznaczona do kodu produkcyjnego ...
Geobits
3
@Claudiu Szczerze przypuszczałem, że to „puch historii”, który zwykle wiąże się z tymi wyzwaniami. Tak czy inaczej, kiedy mówiłem „ta strona ...” miałem na myśli PP&CG, ponieważ większość kodu tutaj nie jest wyraźnie przeznaczona do użytku w produkcji. Szczerze mówiąc, jeśli szuka rzeczywistego kodu do wykorzystania na swojej stronie, bardziej etyczne byłoby zrobienie go samemu lub zlecenie go;)
Geobits
8
@chilemagic you can use any code... więc OP przepisze swoją stronę, aby użyć rozwiązania APL / CJAM / GolfScript? To wyzwanie oparte na prawdziwej historii. Głosuję w górę
edc65
4
To dość trywialne zadanie, dlaczego OP miałby tyle wysiłku wpisywać pytanie, skoro łatwiej byłoby po prostu sam je napisać? Tak czy inaczej, lubiłem próbować.
James Williams

Odpowiedzi:

27

Rubin

Pomyślałem, że byłoby interesujące wyodrębnić skróty stanowe bez wyraźnego wpisywania nazwisk lub skrótów. Ten nie bierze pod uwagę błędnej pisowni danych wejściowych, ponieważ nie obchodzi nas coś takiego na 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

Wymyślenie sprytnych wzorów pasujących do wszystkich stanów zajęło sporo czasu. Kolejność wzorów jest ważna - każdy kolejny wzór stosuje się do pozostałych stanów, które nie zostały dopasowane przez poprzedni wzór:

Wszystkie stany z dwoma słowami używają pierwszych liter tych dwóch słów:

N ew H ampshire, N ew J ersey, N ew M exico, N ew Y racy, N Orth C arolina, N Orth D Akota, R Hode I sland, S OUtH C arolina, S OUtH D Akota, W est V irginia

Wszystkie stany rozpoczynające się od dowolnej litery w { CDGHKLPV} używają pierwszej i ostatniej litery w nazwie:

C aliforni a , C olorad o , C onnecticu t , D elawar e , G eorgi a , H awai i , K ansa s , K entuck y , L ouisian a , P ennsylvani a , V irgini a , V ermon t

Z pozostałych stanów litery { ZVX} są unikalne:

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

Wszystkie pozostałe stany zaczynające się od { FNOUW} używają dwóch pierwszych liter.

Fl orida, Ne braska, Oh io, Ok lahoma, Or egon , Ut ah, Wa shington, Wi sconsin, Wy oming

Zatem { DNR} są unikatowe jako drugie litery:

Ar Kansas, In Diana, Id Aho

Naprawdę trudno jest tworzyć ogólne wzory, ale ...

Tylko trzy pozostałe stany używają podwójnej Nlub L, a podwójna litera jest używana w skrócie stanu:

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

Alub Opo podwójnym S jest unikalny dla

M ass a chusetts i M iss O URI

Ilekroć { SNW} pojawia się przed innymi literami w nazwach pozostałych stanów, litery po nich są używane w skrótach:

A las k a, M arylan d , M ain e , M is s issippi, M on t ana, I ow a

Zostały dwa. Używają one dwóch pierwszych liter:

Al abama, Mi chigan


Można oczywiście grać w golfa:

Rubinowy 2 - 191 165 154 znaków

Kolejne 26 znaków wyłączone przez ugloszenie wyrażeń regularnych. Ponadto jeden z oryginalnych wyrażeń regularnych okazał się zbędny!

gets;[/.* (.)/,/^[CDGHKLPV].*(.)$/,/.*([ZVX])/,/^[NFOUW](.)/,/^.([DNR])/,/.*(L|N)\1/,
/.*SS(A|O)/,/.*?[SNW](.)/,/.(.)/].find{|r|$_.upcase=~r}
puts $&[0]+$1
daniero
źródło
„Obecnie mniej niż jedna trzecia wielkości wpisu w Golfscript!” : P Pamiętaj, że Golfscript nie korzysta z Regexes.
Josiah Winslow
I zmieniłem rozmiar. : P
Josiah Winslow
1
(@JosiahWinslow i och, zrób to 3.9575757575 ...: P)
daniero
6
lol dla wyrażenia regularnego boobs w wyjaśnieniu, że nie przetrwał kompresji
masterX244
1
Podoba mi się ta odpowiedź, ale nie jest poprawna, ponieważ nie może wykryć nieprawidłowych danych wejściowych (jak mówisz). Jest nawet konkretny przykładIf something like New Yrok is passed in, the function should return the original value.
edc65
4

DO#

Użyłem znaków znajdujących się już w stanach jako skrótów, aby skrócić ciąg stanu.

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
źródło
1
Niezłe obejście!
Beta Decay
2

JavaScript (E6)

Tutaj większość jest listą nazw, przy użyciu sztuczki camelCase, aby nieco skrócić. Gra w golfa, 617 bajtów.

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
źródło
0

Pyton

Postanowiłem zrobić to jako wyzwanie dla golfa. Sprowadziłem to do 906 713 694 znaków przy pomocy Daniero i 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)

Jeśli jednak moduły są dozwolone (jak moduł us ), mogę sprowadzić go do 130 znaków:

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

A jeśli nie musisz zwracać oryginalnej wartości, gdy stan nie istnieje, mogę ją zmniejszyć do 50 znaków:

import us
print us.states.lookup(raw_input()).abbr
James Williams
źródło
Możesz zapisać około 200 znaków na pierwszym, pozostawiając sjeden duży ciąg, a następnie dzieląc go przecinkami ( ,); Nie potrzeba wszystkich pojedynczych cudzysłowów.
daniero
@daniero Nie mogę uwierzyć, że o tym nie pomyślałem! Zrobię teraz.
James Williams
Możesz usunąć Waszyngton, ponieważ nie jest to stan USA.
NinjaBearMonkey
@hsl Thanks. Wziąłem listę z listy stanów, które znalazłem w Internecie, nie zdając sobie sprawy, że jest tam Waszyngton.
James Williams
0

bash + sed, 291 bajtów

Bezwstydna konwersja rozwiązania Ruby firmy Daniero na 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
źródło
0

Golfscript - 750 653

Większość jest w nazwach stanowych i skrótach.

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

Wyjaśnienie:

{        }%                         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
źródło
Przepraszam, ale po prostu nie widzę sensu, aby brać cały mój skrypt i dodawać tylko kilka bajtów płyty kotłowej; Po prostu nic nie przynosi. Ale dzięki za kredyty, jak sądzę… Z poważaniem, „drugi facet”.
daniero
Przepraszam, wpis trolla. Wiem, że to nie jest prawdziwy wpis.
Josiah Winslow
No to
uważaj
@daniero Hej, przynajmniej wiem, że można mieć wyrażenia regularne w Golfscript! To właściwie jedyny powód, dla którego zrobiłem to lol: p
Josiah Winslow
0

PHP

Moja próba, która nie zakończyła się tak dużym sukcesem, jak się spodziewałem, polega na użyciu długości łańcucha i określonego umiejscowienia znaków w celu wyodrębnienia skrótu z nazwy stanu. Prawdopodobnie możliwe jest lepsze sekwencjonowanie eliminacji nazw.

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

Oczywiście można grać w golfa. To moja pierwsza próba gry w golfa, więc doceniłem wgląd. (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
źródło
0

JavaScript

Wiem, że to nie jest golf golfowy, ale i tak chcę grać w golfa. :)

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 na nowe rzeczy! (Fragmenty stosu)

Rozpad beta
źródło
3
Jest to standardowa luka i obowiązują standardowe luki, o których nie trzeba wyraźnie wspominać.
Ingo Bürk
@ IngoBürk Nie sądzę, by mieściło się to w standardowych lukach ... Pobieranie wymaganych danych z Internetu w taki sam sposób, jak czytanie z pliku.
Beta Decay
2
Więc jest eval(open('a.txt'))również ważny? Jeśli używasz dowolnego rodzaju pliku, musisz również dołączyć ten plik i jego nazwę do liczby znaków. (To nie jest golf golfowy, więc i tak naprawdę nie ma to w tym przypadku znaczenia.)
Klamka
@Doorknob Skoro podnosisz kwestię, że to nie jest golf golfowy, nie rozumiem, dlaczego dostaję głosy negatywne ... Nie naruszyłem żadnych zasad pop popu.
Beta Decay
2
Nie ma powodu, aby głosować, to idealnie w duchu pytania - faworyzuj nowość i użyteczność - i baw się dobrze
edc65