Practical Golf - Estados Unidos [cerrado]

11

Mi familia tiene un negocio de comercio electrónico. En nuestro propio sitio, obligamos a las personas a elegir su estado en un menú desplegable cuando ingresan su dirección, pero a través de otros canales que utilizamos, los clientes pueden ingresar lo que quieran en el cuadro.

A mi madre le encantan las plantillas de facturas que hice para ella, que se generan automáticamente. Pero debido a que son tan bonitas y equilibradas, no puede soportarlo cuando la gente ESCRIBE los nombres de sus estados, o peor aún, escribe algo como "nueva camiseta". Ella dice que arruina la mirada.

A mi papá le gusta que el código sea liviano. Entonces, en lugar de usar un bloque de caja de interruptor, quiere una solución más ágil.

Entonces, el desafío es hacer una función corta que tome las posibles entradas y devuelva una abreviatura de dos letras (en mayúscula, para mamá). Vamos a suponer (defectuoso) que nuestros usuarios pueden deletrear y siempre poner un espacio en el nombre (donde sea necesario) o pasar la abreviatura correcta. El alcance son los 50 estados de EE. UU.

  • Nueva York
  • Nueva York
  • Nueva York
  • Nueva York

son todos insumos aceptables para Nueva York, y deberían dar salida a NY.

Si se pasa algo como New Yrok, la función puede devolver el valor original.

Puedes usar cualquier lenguaje común. Este es un concurso de popularidad, por lo que gana el que tenga más votos al final de una semana. Supongo que esto favorecerá la novedad y la utilidad.

EDITAR: La descripción es historia fluff, pero estaba trabajando en un proyecto similar y pensé que debía haber una forma más interesante de hacerlo. Puedo hacer el proyecto yo mismo (ya lo hice) pero pensé que este era un buen lugar para un desafío más interesante. Por "Cualquier idioma común" excluía las bibliotecas / idiomas personalizados diseñados para este desafío. Intentaba buscar métodos novedosos, en lugar de ayuda gratuita con el código. Me imagino que todos lo han hecho en algún momento, pero sería divertido hacerlo de una manera inusual. Creo que los proyectos más interesantes son aquellos en los que abordas las tareas cotidianas de formas nuevas e interesantes, es por eso que este es un concurso de popularidad en lugar de golf.

Josiah
fuente
14
No estoy seguro de por qué este es un concurso de popularidad en lugar de golf de código (especialmente porque el nombre incluye 'golf' y tu padre favorece el código corto).
Geobits
55
@Claudiu Cierto, pero este sitio no está destinado para el código de producción ...
Geobits
3
@Claudiu Honestamente asumí que se trataba de una "historia falsa" del tipo que generalmente acompaña a estos desafíos. De cualquier manera, cuando dije "este sitio ..." me refería a PP&CG, ya que la mayoría del código aquí no está explícitamente destinado a ser utilizado en producción. Honestamente, si está buscando un código real para usar en su sitio, sería más ético hacerlo él mismo o contratarlo;)
Geobits
8
@chilemagic you can use any code... ¿entonces OP reescribirá su sitio para usar su solución APL / CJAM / GolfScript? Es un desafío basado en una historia real. Voto arriba
edc65
44
Es una tarea bastante trivial, ¿por qué OP haría todo el esfuerzo de escribir una pregunta cuando sería más fácil codificarla él mismo? De cualquier manera, disfruté intentarlo.
James Williams el

Respuestas:

27

Rubí

Pensé que sería interesante extraer las abreviaturas de estado sin escribir ninguno de los nombres o abreviaturas explícitamente. Este no tiene en cuenta la falta de ortografía de la entrada, porque no nos importa tal cosa aquí en codegolf.SE, ¿ verdad ?

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

Tomó un tiempo considerable para descubrir patrones inteligentes para que coincida con todos los estados. El orden de los patrones es importante: cada patrón consecutivo se aplica a los estados restantes que no coincidían con un patrón anterior:

Todos los estados con dos palabras en ellos usan las letras iniciales de las dos palabras:

N ew H ampshire, N ew J ersey, N ew M éxico, N ew Y ork, N Orth C arolina, N Orth D Akota, R hode I sland, S outh C arolina, S outh D Akota, W est V irginia

Todos los estados que comienzan con cualquier letra en { CDGHKLPV} usan la primera y la última letra del nombre:

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

Del resto de los estados, las letras { ZVX} son únicas:

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

Todos los estados restantes que comienzan con { FNOUW} usan las dos primeras letras.

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

Entonces, { DNR} son únicos como segundas letras:

Ar kansas, en diana, Id aho

Realmente se está haciendo difícil hacer patrones generales, pero ...

Solo tres estados restantes usan doble No L, y la doble letra se usa en la abreviatura de estado:

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

Ao Odespués de doble S es exclusivo de

M ass a chusetts y M iss o uri

Siempre que { SNW} aparezca antes de otras letras en los nombres de estado restantes, las letras después de ellas se usan en las abreviaturas:

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

Dos a la izquierda. Estos usan las dos primeras letras:

Al abama, mi chigan


Se puede jugar al golf, por supuesto:

Ruby 2 - 191 165 154 caracteres

Otros 26 caracteres apagados al uglificar un poco las expresiones regulares. Además, ¡una de las expresiones regulares originales resultó ser redundante!

gets;[/.* (.)/,/^[CDGHKLPV].*(.)$/,/.*([ZVX])/,/^[NFOUW](.)/,/^.([DNR])/,/.*(L|N)\1/,
/.*SS(A|O)/,/.*?[SNW](.)/,/.(.)/].find{|r|$_.upcase=~r}
puts $&[0]+$1
daniero
fuente
"¡Actualmente menos de un tercio del tamaño de la entrada Golfscript!" : P Tenga en cuenta que Golfscript no utiliza expresiones regulares.
Josiah Winslow
Y cambié el tamaño. : P
Josiah Winslow
1
(@JosiahWinslow y oh, haz que 3.9575757575 ...: P)
daniero
66
jajaja por las tetas regex en la explicación que no sobrevivió a la compresión
masterX244
1
Me gusta esta respuesta, pero no es válida ya que no puede detectar entradas no válidas (como usted dice). Incluso hay un ejemplo específicoIf something like New Yrok is passed in, the function should return the original value.
edc65
4

C#

Usé caracteres ya en los estados para las abreviaturas para acortar la cadena 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
fuente
1
Buena solución!
Beta Decay
2

JavaScript (E6)

Aquí el grueso es la lista de nombres, usando el truco camelCase para acortar un poco. Golfizado, 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
fuente
0

Pitón

Decidí hacer esto como un desafío de código de golf. Lo reduje a 906 713 694 caracteres con la ayuda de daniero y 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)

Sin embargo, si se permiten módulos (como el módulo us ), puedo reducirlo a 130 caracteres:

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

Y si no tuviera que devolver el valor original cuando el estado no existe, podría reducirlo a 50 caracteres:

import us
print us.states.lookup(raw_input()).abbr
James Williams
fuente
Puede guardar aproximadamente 200 caracteres en el primero dejando que ssea ​​una cadena grande y luego dividirla en comas ( ,); No hay necesidad de todas las comillas simples.
daniero
@daniero ¡No puedo creer que no haya pensado en eso! Lo hare ahora.
James Williams
Puede eliminar Washington, DC, ya que no es un estado de EE. UU.
NinjaBearMonkey
@hsl Gracias. Tomé la lista de una lista de estados que encontré en línea, no me di cuenta de que Washington DC estaba allí.
James Williams el
0

bash + sed, 291 bytes

Conversión descarada de la solución Ruby de Daniero a 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
fuente
0

Golfscript - 750 653

El grueso está en los nombres y abreviaturas de los estados.

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

Explicación:

{        }%                         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
fuente
Lo siento, pero simplemente no veo el punto de tomar todo mi script y agregar nada más que unos pocos bytes de repetitivo; Simplemente no trae nada. Pero gracias por los créditos, supongo ... Atentamente, "el otro tipo".
daniero
Lo siento, entrada troll. Sé que no es una entrada real.
Josiah Winslow
Bueno, considérame trolleado entonces;)
daniero
@daniero ¡Hola, al menos sé que es posible tener expresiones regulares en Golfscript! Esa es la única razón por la que hice eso jajaja: p
Josiah Winslow
0

PHP

Mi intento, que no fue tan exitoso como esperaba, usa la longitud de la cadena y una colocación específica de caracteres para extraer la abreviatura del nombre del estado. Probablemente sea posible una mejor secuencia de la eliminación del nombre.

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

Por supuesto, se puede jugar al golf. Este es mi primer intento de jugar al golf, por lo que aprecio la comprensión. (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
fuente
0

Javascript

Sé que esto no es golf de código, pero quiero jugarlo de todos modos. :)

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 por cosas nuevas! (Fragmentos de pila)

Decaimiento Beta
fuente
3
Esta es una escapatoria estándar y las lagunas estándar se aplican sin tener que mencionarse explícitamente.
Ingo Bürk
@ IngoBürk No creo que esto caiga dentro de las lagunas estándar ... Está obteniendo los datos requeridos de Internet de la misma manera que leer un archivo.
Beta Decay
2
Entonces, ¿ eval(open('a.txt'))también es válido? Si usa un archivo de cualquier tipo, también debe incluir ese archivo y su nombre en el recuento de caracteres. (Esto no es código golf, por lo que en realidad no importa en este caso de todos modos.)
Pomo de la puerta
@Doorknob Dado que usted plantea el punto de que esto no es código golf, no veo por qué recibo votos negativos ... No he violado ninguna regla de contras pop.
Beta Decay
2
No hay razón para rechazar, está perfectamente en el espíritu de la pregunta: favorecer la novedad y la utilidad, y la diversión
Edc65