Golf pratique - États américains [fermé]

11

Ma famille a une entreprise de commerce électronique. Sur notre propre site, nous forçons les gens à choisir leur état dans un menu déroulant lorsqu'ils entrent leur adresse, mais via certains autres canaux que nous utilisons, les clients peuvent entrer tout ce qu'ils veulent dans la boîte.

Ma maman adore les modèles de factures que j'ai créés pour elle, qui sont générés automatiquement. Mais parce qu'ils sont si jolis et équilibrés, elle ne peut pas le supporter quand les gens écrivent le nom de leur état, ou pire, écrivent quelque chose comme "new jersey". Elle dit que ça gâche le look.

Mon père aime que le code soit léger. Donc, plutôt que d'utiliser un bloc de boîtier de commutation, il veut une solution plus légère.

Le défi consiste donc à créer une fonction courte qui prend les entrées possibles et renvoie une abréviation à deux lettres (en majuscule, pour maman). Nous allons faire une supposition (erronée) que nos utilisateurs peuvent épeler et toujours mettre un espace dans le nom (si nécessaire) ou passer l'abréviation correcte. La portée est les 50 États américains.

  • New York
  • New York
  • New York
  • New York

sont tous des entrées acceptables pour New York et devraient produire NY.

Si quelque chose comme New Yrok est passé, la fonction peut retourner la valeur d'origine.

Vous pouvez utiliser n'importe quel langage commun. C'est un concours de popularité, donc celui qui a le plus de votes à la fin d'une semaine gagne. Je suppose que cela favorisera la nouveauté et l'utilité.

EDIT: La description est une histoire, mais je travaillais sur un projet similaire et je pensais qu'il devait y avoir une façon plus intéressante de le faire. Je peux faire le projet moi-même (je l'ai déjà fait) mais je pensais que c'était un bon endroit pour un défi plus intéressant. Par "Tout langage commun", j'excluais les langages / bibliothèques personnalisés conçus pour ce défi - j'essayais de chercher de nouvelles méthodes, plutôt que de l'aide de code gratuite. Je pense que tout le monde l'a fait à un moment donné, mais ce serait amusant de le faire de manière inhabituelle. Je trouve que les projets les plus intéressants sont ceux où vous abordez les tâches quotidiennes de manière nouvelle et intéressante - c'est pourquoi il s'agit d'un concours de popularité plutôt que de golf.

Josiah
la source
14
Je ne sais pas pourquoi il s'agit d'un concours de popularité au lieu du golf de code (d'autant plus que le nom comprend «golf» et que votre père privilégie le code court).
Geobits
5
@Claudiu C'est vrai, mais ce site n'est pas destiné au code de production ...
Geobits
3
@Claudiu J'ai honnêtement supposé que c'était du "fluff" du genre qui accompagne généralement ces défis. Quoi qu'il en soit, quand j'ai dit "ce site ...", je voulais dire PP&CG, car la plupart du code ici n'est explicitement pas destiné à être utilisé en production. Honnêtement, s'il cherche du code réel à utiliser sur son site, il serait plus éthique de le faire lui-même ou de le sous-traiter;)
Geobits
8
@chilemagic you can use any code... donc OP réécrira son site pour utiliser votre solution APL / CJAM / GolfScript? C'est un défi basé sur une histoire vraie. Je vote
edc65
4
C'est une tâche assez banale, pourquoi OP ferait-il tout l'effort de taper une question alors qu'il serait plus facile de la coder lui-même? Quoi qu'il en soit, j'ai aimé essayer.
James Williams

Réponses:

27

Rubis

J'ai pensé qu'il serait intéressant d'extraire les abréviations d'état sans écrire explicitement aucun des noms ou abréviations. Celui-ci ne prend pas en compte l'orthographe de l'entrée, car nous ne nous soucions pas de cette chose ici sur 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

Il a fallu un temps considérable pour trouver des modèles intelligents pour correspondre à tous les états. L'ordre des modèles est important - chaque modèle consécutif s'applique aux états restants qui ne correspondaient pas à un modèle précédent:

Tous les États contenant deux mots utilisent les lettres initiales des deux mots:

N de H de ampshire, N de J de ersey, N de M de exique, N de Y de ork, N orth C arolina, N orth D Akota, R hode I sland, S ud C arolina, S outh D Akota, W is V irginia

Tous les États commençant par une lettre en { CDGHKLPV} utilisent la première et la dernière lettre du nom:

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

Parmi les autres états, les lettres { ZVX} sont uniques:

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

Tous les autres états commençant par { FNOUW} utilisent les deux premières lettres.

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

Ensuite, { DNR} sont uniques en tant que secondes lettres:

Ar kansas, In diana, Id aho

Il devient vraiment difficile de faire des modèles généraux, mais ...

Seuls trois états restants utilisent le double Nou L, et la double lettre est utilisée dans l'abréviation d'état:

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

Aou Oaprès le double S est unique à

M ass a chusetts et M iss o uri

Chaque fois que { SNW} apparaît avant les autres lettres dans les noms d'état restants, les lettres qui les suivent sont utilisées dans les abréviations:

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

Il en reste deux. Ceux-ci utilisent les deux premières lettres:

Al abama, Mi chigan


Il peut être joué au golf bien sûr:

Rubis 2-191 165 165 154 caractères

Encore 26 caractères de moins en uglifiant un peu les regex. De plus, l'un des regex d'origine s'est avéré redondant!

gets;[/.* (.)/,/^[CDGHKLPV].*(.)$/,/.*([ZVX])/,/^[NFOUW](.)/,/^.([DNR])/,/.*(L|N)\1/,
/.*SS(A|O)/,/.*?[SNW](.)/,/.(.)/].find{|r|$_.upcase=~r}
puts $&[0]+$1
daniero
la source
"Actuellement, moins d'un tiers de la taille de l'entrée Golfscript!" : P Gardez à l'esprit, Golfscript n'utilise pas Regexes.
Josiah Winslow
Et j'ai changé la taille. : P
Josiah Winslow
1
(@JosiahWinslow et oh, faites ça 3.9575757575 ...: P)
daniero
6
lol pour le regex boobs dans l'explication qui
n'a
1
J'aime cette réponse, mais elle n'est pas valide car elle ne peut pas détecter une entrée invalide (comme vous le dites). Il y a même un exemple spécifiqueIf something like New Yrok is passed in, the function should return the original value.
edc65
4

C #

J'ai utilisé des caractères déjà dans les états pour les abréviations pour raccourcir la chaîne d'état.

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
la source
1
Belle solution de contournement!
Beta Decay
2

JavaScript (E6)

Ici, l'essentiel est la liste des noms, en utilisant l' astuce camelCase pour raccourcir un peu. Golfé, 617 octets.

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
la source
0

Python

A décidé de le faire comme un défi de golf de code. Je suis descendu à 906 713 694 caractères avec l'aide de daniero et 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)

Cependant, si les modules sont autorisés (comme le module américain ), je peux le réduire à 130 caractères:

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

Et si vous n'aviez pas à retourner la valeur d'origine lorsque l'état n'existe pas, je pourrais la réduire à 50 caractères:

import us
print us.states.lookup(raw_input()).abbr
James Williams
la source
Vous pouvez enregistrer environ 200 caractères sur le premier en laissant sune grande chaîne, puis la diviser par des virgules ( ,); Pas besoin de toutes les guillemets simples.
daniero
@daniero Je n'arrive pas à croire que je n'y ai pas pensé! Fera maintenant.
James Williams
Vous pouvez supprimer Washington, DC, car ce n'est pas un État américain.
NinjaBearMonkey
@hsl Merci. J'ai pris la liste d'une liste d'États que j'ai trouvés en ligne, je ne savais pas que Washington DC était là.
James Williams
0

bash + sed, 291 octets

Conversion sans vergogne de la solution Ruby de Daniero en 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
la source
0

Golfscript - 750 653

La majeure partie se trouve dans les noms et abréviations des États.

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

Explication:

{        }%                         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
la source
Désolé, mais je ne vois pas l'intérêt de prendre tout mon script et de n'ajouter que quelques octets de passe-partout; Cela n'apporte simplement rien. Mais merci pour le générique, je suppose ... Bien à vous, "l'autre gars".
daniero
Désolé, entrée troll. Je sais que ce n'est pas une vraie entrée.
Josiah Winslow
Eh bien, considérez-moi alors
trollé
@daniero Hé, au moins je sais qu'il est possible d'avoir des expressions régulières dans Golfscript! C'est en fait la seule raison pour laquelle j'ai fait ça lol: p
Josiah Winslow
0

PHP

Ma tentative, qui n'a pas été aussi réussie que je l'avais espéré, utilise une longueur de chaîne et un placement de caractère spécifique pour extraire l'abréviation du nom de l'état. Un meilleur séquençage de l'élimination des noms est probablement possible.

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

Bien sûr, il peut être joué au golf. Ceci est ma première tentative de golf, donc un aperçu apprécié. (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
la source
0

Javascript

Je sais que ce n'est pas du golf de code, mais je veux quand même jouer au golf. :)

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)

Ouais pour de nouvelles choses! (Empiler des extraits)

Beta Decay
la source
3
Il s'agit d'une échappatoire standard et les échappatoires standard s'appliquent sans avoir à être mentionnées explicitement.
Ingo Bürk
@ IngoBürk Je ne pense pas que cela relève des lacunes standard ... Il s'agit d'obtenir les données requises sur Internet de la même manière que la lecture d'un fichier.
Beta Decay du
2
Est-ce donc eval(open('a.txt'))également valable? Si vous utilisez un fichier de quelque nature que ce soit, vous devez également inclure ce fichier et son nom dans votre nombre de caractères. (Ce n'est pas du golf de code, donc ça n'a pas vraiment d'importance dans ce cas de toute façon.)
Poignée de porte
@ Doorknob Puisque vous soulevez le fait que ce n'est pas du golf de code, je ne vois pas pourquoi je reçois des downvotes ... Je n'ai violé aucune règle de contre-pop.
Beta Decay
2
Aucune raison de voter contre, c'est parfaitement dans l'esprit de la question - privilégiez la nouveauté et l'utilité - et le plaisir
edc65