28
votes
\$\begingroup\$

This challenge has ended! Congratulations Flonk!

I was sure I would get a good grade, but after turning in Flonk's my work, my professor did not believe it was mine and also could not understand why it was so complicated... I failed and my mom grounded me from Facebook and Minecraft for a month. I don't understand. :(

Thanks for all your submissions! Some great answers here. The official winner is Flonk with a score of 64. The top 5 are:

  1. Flonk, 64 (Haskell, with efficient maths!)
  2. DigitalTrauma, 40 (The cloud, the future is now)
  3. primo, 38 (Python, and my personal favorite - and very professional much!)
  4. Sylwester, 20 (Racket, although Janember is stretching it!)
  5. ilmale, 16 (A highly optimized algorithm in Lua)

Original challenge below.


Please help me, it's very urgent!!! :(

I need to convert shortened versions of month names to their longer representations (e.g "Dec" -> "December"), case-insensitive. Right now I'm using Java; the month's name is a String and I would rather not convert it to a Date object first. Any language will do, though.

Is there an easy way to do this?? Go easy please I am a newbie to programming!


This is a code trolling popularity contest (the best kind there is!). The answer with the most upvotes on Apr 8, 2014 wins.

\$\endgroup\$
4
  • 7
    \$\begingroup\$ "Please help me, it's very urgent!!! :(" <<< do my homework, do it quick? \$\endgroup\$
    – user19214
    Apr 2, 2014 at 7:42
  • 13
    \$\begingroup\$ @yeti As quick as you can!! Hurry before I fail my class! \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 7:42
  • 24
    \$\begingroup\$ There should be a feature that would secretly copy such questions from Stackoverflow to codegolf.SE with a code-trolling tag, and then have the answers from codegolf.SE transferred back to the original post with the text in spoiler tags removed. \$\endgroup\$
    – daniero
    Apr 2, 2014 at 12:49
  • \$\begingroup\$ Code-trolling is in the process of being removed, as per the official stance. This question is very highly voted with many answers, many of which are extremely highly voted. It recieved just over 50% "delete" votes on the poll, but it is unique in that it recieved so many answers and votes, so I am locking it for historical significance. \$\endgroup\$
    – Doorknob
    May 11, 2014 at 23:11

29 Answers 29

74
votes
\$\begingroup\$

It's really simple with a little polynomial interpolation!

First, I looked at the list of short month names

["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]

and checked the sum of their characters ASCII values

[313,301,320,323,327,333,331,317,328,326,339,300]

then subtracted 300 from those to get a grasp of what I'm dealing with here, and prepared an Array that contains all the longer versions of the months' names.

[13,1,20,23,27,33,31,17,28,26,39,0]
mons = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

I guess you can see what's going on now - all I need is a function getIndex that maps 13 to 0, 1 to 1, 20 to 2, and so on, so I can simply do

getMonthName shortname = mons !! (getIndex shortname)

Luckily, Wolfram|Alpha can do this for me! The numbers get a bit large, but Haskell can handle that with grace. We just need to make sure to round the results, because floating-point-arithmetic is a little imprecise! So there you go, fast, elegant, and idiomatic Haskell:

import Data.Char

getIndex x = round $ 11 -
    (220797068189915461*x)/11644212222720 +
    (184127469431441671621*x^2)/6982771136140800 -
    (8800438195450444577647153*x^3)/1013060436431307264000 +
    (2826703553741192361967823*x^4)/2026120872862614528000 -
    (269098602165195540339443*x^5)/2026120872862614528000 +
    (13744405529566098359*x^6)/1692665725031424000 -
    (13060656886070844161*x^7)/39727860252208128000 +
    (5939638907108115199*x^8)/675373624287538176000 -
    (303426664924585177*x^9)/2026120872862614528000 +
    (2983240583426137*x^10)/2026120872862614528000 -
    (12901227927103*x^11)/2026120872862614528000

mons = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
getMonthName = (mons!!).getIndex.subtract 300.fromIntegral.sum.fmap (ord.toLower)

Run it simply like this:

λ> getMonthName "DeC"
"December"

λ> getMonthName "jan"
"January"
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Very good and integers are very efficient I'm sure my instructor will like my work! \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 21:19
  • 8
    \$\begingroup\$ +1 for teaching me about interpolating polynomial. \$\endgroup\$
    – primo
    Apr 5, 2014 at 3:26
  • 3
    \$\begingroup\$ I did have to laugh when reading your first sentence. \$\endgroup\$
    – Anaphory
    Apr 5, 2014 at 10:51
46
votes
\$\begingroup\$

Bash + GNU tools + "the cloud"

Google has the answer to everything, and I'm feeling lucky:

wget -qU Mozilla -O- "http://www.google.com/search?q=$1+month&btnI" | grep -Eo "<title>[[:alpha:]]+" | cut -d\> -f2

In use:

$ ./longmonth.sh jan
January
$ ./longmonth.sh feb
February
$
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Well played sir! \$\endgroup\$
    – ojblass
    Apr 2, 2014 at 5:42
  • \$\begingroup\$ Wouldn't [a-zA-Z] work as a replacement for [[:alpha:]] (seems that way when I try it at least)? That would save 3 chars. A few more chars could be saved by querying ask.com, but that might not be as reliable. \$\endgroup\$
    – Michael
    Apr 2, 2014 at 8:53
  • 7
    \$\begingroup\$ @Mic which would matter if this were code golf \$\endgroup\$ Apr 2, 2014 at 12:07
  • 7
    \$\begingroup\$ @JasonC Its a "cloud-based" solution. Surely no other justification is needed. \$\endgroup\$ Apr 2, 2014 at 20:59
  • 4
    \$\begingroup\$ @DigitalTrauma Dear sir Ive heard of the cloud and it is very professional! Very good! Very convinced! Ty -JasonC \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 21:15
43
votes
\$\begingroup\$

Python

Because this function is very important, it will probably be used a lot, so you should try to make it as fast as possible. Other posters have recommended using a hashmap look-up... don't do this! Hashmaps are really slow compared to arrays. You just need to convert each abbreviation to a number. There's a standard hashing technique that can be used for this:

index = reduce(int.__mul__, (ord(c) for c in abbr))

This is almost guaranteed to be unique, and lots of professional tools use this.

Now you need to create a look-up function:

def month_abbr_to_name(abbr):
  months = ["Unknown"] * 2000000

  months[679932]  = "December"
  months[692860]  = "Febuary"
  months[783315]  = "August"
  months[789580]  = "January"
  months[829920]  = "April"
  months[851466]  = "March"
  months[903749]  = "May"
  months[907236]  = "October"
  months[935064]  = "July"
  months[938896]  = "September"
  months[952380]  = "June"
  months[1021644] = "November"

  index = reduce(int.__mul__, (ord(c) for c in abbr))

  month_name = months[index]

  if month_name == "Unknown":
    raise ValueError("Invalid month abbreviation!")

  return month_name

And use it like this:

print month_abbr_to_name("Dec")December

HTH!


Trolling

- This code is horrendously slow. Although array access is indeed faster than hashmaps, this doesn't apply if the array is thousands of times larger than the necessary hashmap would be.
- This incredibly large array is created again, and again, every time the function is called. To waste a little more space, each value is initialized with "Unknown".
- The hashing function is meant to be obscure to someone unfamilar with Python. I add that it is "used in lots of professional tools" to discourage investigation.
- The hashing function is unique enough to distiquish between the twelve months correctly, but will not catch many common typos, such as swapped characters.
- Just about any string longer than 3 chars will crash on array index out of bounds.
- "Febuary" is misspelled.
- "This function is very important." Minor ego-rub for the OP.

\$\endgroup\$
4
  • 12
    \$\begingroup\$ Take a good look, folks; this is a proper code-trolling answer! Ps. Im sure I will get a good grade with this and its much better then the sloooow Java shell script I try to writE?![enter image description here] \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 9:05
  • 2
    \$\begingroup\$ "Febuary" is misspelled. -- some serious trolling :) \$\endgroup\$
    – Jaa-c
    Apr 4, 2014 at 1:35
  • 10
    \$\begingroup\$ +1 for saying that hash tables are inefficient, then implementing a really inefficient hash table \$\endgroup\$
    – James_pic
    Apr 4, 2014 at 8:59
  • 1
    \$\begingroup\$ "Hashmaps are really slow compared to arrays. You just need to convert each abbreviation to a number. There's a standard hashing technique that can be used for this..." so in other words reimplement a hash map. Hah. +1 \$\endgroup\$
    – wchargin
    Apr 9, 2014 at 3:39
25
votes
\$\begingroup\$

Racket

I go for a KISS solution. I've test it with OP's use case "Dec" with all caps to check if the correct result is returned. It passed with flying colors.

(define (long-month short-month)
  (define end "ember")   
  (string-titlecase 
   (string-append short-month end)))

;; Test OP's use case
(long-month "DEC") ;;==> "December"

Obviously the trolling here is that it only works for a few cases so it's useless :-)

\$\endgroup\$
6
  • \$\begingroup\$ Probably because, from the code-trolling tag wiki, "The task is to give code that works, but is useless, severely frustrating the OP. " Your code doesn't even work. Here, have another downvote. \$\endgroup\$
    – user12205
    Apr 2, 2014 at 13:41
  • \$\begingroup\$ @ace It doesn't throw any errors and it returns the correct answer "December". The question didn't specify it should work for other months or what long names they would have so I'm expecting adding "ember" to the end is a good troll answer. \$\endgroup\$
    – Sylwester
    Apr 2, 2014 at 14:10
  • 1
    \$\begingroup\$ From the question, "I need to convert shortened versions of month names to their longer representations (e.g "Dec" -> "December")" December is an example, not all cases. Your program should work for all month names. \$\endgroup\$
    – user12205
    Apr 2, 2014 at 14:19
  • 9
    \$\begingroup\$ @ace And it does. It turns "Jan" into "Janember" Looking at the example that exactly what the OP wants. I can't really see how one can downvote answer for code-trolling tags since "Deliberately misinterpreting the question" and "cheat on the question" are both good ways to answer it. \$\endgroup\$
    – Sylwester
    Apr 2, 2014 at 14:25
  • 7
    \$\begingroup\$ This is exactly the type of solution I was thinking of offering, with a "disclaimer: you said it was urgent, so I rushed and only tested 3 cases, but it passed for all of them". \$\endgroup\$
    – AShelly
    Apr 2, 2014 at 19:33
22
votes
\$\begingroup\$

LUA

My solution will work in your locale language, your professor will be happy

input = ...
found = false
input = string.lower(input)

i = 12
while i > 0 do
   abb = os.date("%b")
   if string.lower(abb) == input then
      print(os.date("%B"))
      return
   end
   os.execute('sleep 28d')
   i = i - 1
end
print('not found')

Test

lua 25207.lua aPr
April

Check the abbreviation of the current month, if correct return the long string otherwise try again.. ONE MONTH LATER

\$\endgroup\$
1
  • \$\begingroup\$ Brilliant! Reminds me of the time in my old job when I was <<<Error: connection timed out.>>> \$\endgroup\$ Apr 6, 2014 at 19:14
13
votes
\$\begingroup\$

Perl

use re 'eval';$_=lc<>;
s/b/br/;s/an|br/$&uary/;s/(?<!u)ar/arch/;s/r$/ril/;s/p$/pt/;s/t|v|c$/$&ember/;
s/ju(.)/$&.$1=~tr\/nl\/ey\/r/e;s/(?<=g)/ust/;s/ctem/cto/;
print ucfirst;

- Regex hell. I hope regex doesn't count as "trolling by obscure language".
- Extremely fragile. You'd have a hard time adding a support for Bugsember.
- Unreadable. Pattern inside pattern makes it even more so.
- Compression of June and July into a single statement doesn't actually compress anything.
- random usage of lookbehind for g, while others repeat the pattern in the substitution.
- use re 'eval' is actually not needed; it's only used when a variable pattern is wanted. Also, use of eval to "gain" a little "compression".

\$\endgroup\$
2
  • 17
    \$\begingroup\$ Looks like normal Perl to me... \$\endgroup\$ Apr 3, 2014 at 15:02
  • 1
    \$\begingroup\$ @PeterOlson the language was chosen to suit the algorithm, but the algorithm doesn't suit the task at all, don't you agree? :-) \$\endgroup\$ Apr 3, 2014 at 15:38
10
votes
\$\begingroup\$

Java

You said your current code's in Java, so I thought I'd make things easy for you.

// The standard library's there, so you should use it
import static java.util.Calendar.*;

public class MonthConverter {

  private static int shortNameToNumber(String shortName) {
    int i;
    switch (shortName) {
      case "jan": i = 1;
      case "feb": i = 2;
      case "mar": i = 3;
      case "apr": i = 4;
      case "may": i = 5;
      case "jun": i = 6;
      case "jul": i = 7;
      case "aug": i = 8;
      case "sep": i = 9;
      case "oct": i = 10;
      case "nov": i = 11;
      case "dec": i = 12;
      default: i = 0;
    }
    return i;
  }

  private static String numberToLongName(int month) {
    switch (month) {
      case JANUARY: return "January";
      case FEBRUARY: return "February";
      case MARCH: return "March";
      case APRIL: return "April";
      case MAY: return "May";
      case JUNE: return "June";
      case JULY: return "July";
      case AUGUST: return "August";
      case SEPTEMBER: return "September";
      case OCTOBER: return "October";
      case NOVEMBER: return "November";
      case DECEMBER: return "December";
      default: return "Unknown";
    }
  }
  
  public static String fullName(String shortName) {
    return numberToLongName(shortNameToNumber(shortName));
  }
  
  public static void main(String[] args) {
    // Always test your code
    System.out.println("jan is: " + fullName("jan"));
    assert fullName("jan").equals("January");
  }
}

The Calendar class has a fun little gotcha where months are numbered starting at 0 - so JANUARY == 0. However, this clearly can't affect our code, as we test it, right? Notice that there's an unintended switch fallthrough in shortNameToNumber, which means every month ends up being 0. Handily, JANUARY == 0, so our test passes.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Oh god, I didn't notice the lack of breaks in the switch statement. It's been such a long time since I've used a switch. \$\endgroup\$
    – Joe Z.
    Apr 23, 2014 at 1:06
10
votes
\$\begingroup\$

Bash + coreutils + paq8hp12

The answer that is currently upvoted the most has to access the internet for every query. In addition to being very inefficient, this also means that your script will fail if there's no internet.

It's better to store the necessary information on your hard disk. Of course, you could store just the data needed for this very script, but that would require different data for different tasks. It is much better to store all data you could possibly need in a single multi-purpose file.

# This script is supposed to output only the wanted information, so we'll have to close
# STDERR and make sure accidental keyboard presses don't show any characters on the screen.

exec 2>&-
stty -echo

# Unfortunately, Bash doesn't have goto labels. Without them, it's impossible to use if
# statements, so we'll implement them.

goto()
{
    exec bash <(egrep -A 1000 "^: $1" $0) $BASH_ARGV
}

# We'll need enwik8, a magic file containing all the important Wikipedia data. EVERYTHING
# can be found on Wikipedia, so this file contains all the information any script could
# possibly need.

ls | grep -q enwik8 && goto alreadydownloaded

# Too bad.

wget http://mattmahoney.net/dc/enwik8.zip
unzip enwik8.zip

# ZIP is a very wasteful format and hard disk space is expensive. It is best to compress
# the file using a more efficient algorithm.

wget http://mattmahoney.net/dc/paq8hp12any_src.zip
unzip paq8hp12any_src.zip

# Make the compression program executable and compress the magic Wikipedia file.

chmod +x paq8hp12_l64
./paq8hp12_l64 enwik8.paq8 enwik8

: alreadydownloaded

# Extract the enwik8 file from the paq archive.

./paq8hp12_l64 enwik8.paq8 enwik8

# Now we use a simple POSIX Basic Regular Expression to find the required information in
# the file.

cat enwik8 | egrep -io "[0-9].[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?[a-z]?.[0-9]" | sort | uniq -c | sort -n | tac | egrep -o "$1[a-z]*" | sort | uniq -c | sort -n | tac | head -n 1 | cut -d ' ' -f 7

# We're done.

Trolling

  • Closes STDERR, so we won't be able to debug the script if it fails.

  • Disables input echoing, which persists after the script has finished. If executed from a terminal, you have to execute stty echo to get your terminal usable again. If not executed from a terminal, this could crash the script.

  • Requires implementing goto first. As if that wasn't bad enough on its own, the goto function won't work if the script's filename contains spaces.

  • We won't download the archive if a file containing the string enwik8 exists in the current directory. This might work.

  • Downloading a 100 MB file (even if compressed to 36 MB) is obviously overkill for this task. Plus, enwik8 contains the first 100 MB of a 4+ GB Wikipedia dump, so for a specific task, it's unlikely to contain any useful information.

  • Compressing the file with paq8hp12 shrinks it to 16 MB, but compression and decompression both take one hour. It actually will do both the first time this script is run.

  • The script doesn't delete the zipped or raw version of enwik8, so shrinking it to 16 MB consumed even more hard disk space.

  • The compression utility will only work on 64-bit processors.

  • It leaves all the files that have been downloaded or extracted in the current directory.

  • It doesn't explain the most tricky part of the script, which is the regex-pipe monster. It basically extracts all strings between 4 and 19 bytes that have a leading and trailing digit, sorts those strings by number of occurrences, filters the strings containing the short month name, sorts again by number of occurrences and displays the most frequent.

  • Even if the above was a good idea, cat is unneeded at the beginning, egrep is rather slow for this task, the regex will return a lot of false positives (everything could be done with one regex), the first sort | uniq -c | sort -n | tac accomplishes absolutely nothing, it uses sort | tac instead of sort -r and cut won't work reliably since the number of spaces at the beginning is variable.

  • The regex is an Extended POSIX Regular Expression, so googling the BRE syntax won't help at all.

  • Returns Nov instead of November and 6 instead of August.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ These are very helpful advice! Surely this is more efficient and my instructor told me that professionals make data reusable for OOP and OOP is fast and better! \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 19:55
9
votes
\$\begingroup\$

Python + SQLite

Many of the answers so far make the mistake of hard-coding the month names. But, you never know when some Pope or President is going to make us switch to another calendar, and then tons of date parsing/formatting code will instantly become worthless! (Or, more commonly, when you need to internationalize your program.)

What you need is a database.

CREATE TABLE tblShortMonthNames (
   MonthAbbr CHAR(3) PRIMARY KEY NOT NULL COLLATE NOCASE,
   MonthID   INTEGER NOT NULL
);

CREATE TABLE tblFullMonthNames (
   MonthID   INTEGER PRIMARY KEY,
   MonthName VARCHAR(9) NOT NULL
);

INSERT INTO tblFullMonthNames VALUES (1, 'January');
INSERT INTO tblFullMonthNames VALUES (2, 'February');
INSERT INTO tblFullMonthNames VALUES (3, 'March');
INSERT INTO tblFullMonthNames VALUES (4, 'April');
INSERT INTO tblFullMonthNames VALUES (5, 'May');
INSERT INTO tblFullMonthNames VALUES (6, 'June');
INSERT INTO tblFullMonthNames VALUES (7, 'July');
INSERT INTO tblFullMonthNames VALUES (8, 'August');
INSERT INTO tblFullMonthNames VALUES (9, 'September');
INSERT INTO tblFullMonthNames VALUES (10, 'October');
INSERT INTO tblFullMonthNames VALUES (11, 'November');
INSERT INTO tblFullMonthNames VALUES (12, 'December');

INSERT INTO tblShortMonthNames
   SELECT SUBSTR(MonthName, 1, 3), MonthID FROM tblFullMonthNames;

Then, just write a simple program to query it.

import sqlite3
import sys

QUERY = """SELECT tblFullMonthNames.MonthName
FROM tblShortMonthNames INNER JOIN tblFullMonthNames USING (MonthID)
WHERE tblShortMonthNames.MonthAbbr = ?"""

with sqlite3.connect('months.db') as db:
    for abbr in sys.argv[1:]:
        row = db.execute(QUERY, [abbr]).fetchone()
        if row:
            print(row[0])
        else:
            print(abbr + ' is not a valid month name.')
\$\endgroup\$
0
5
votes
\$\begingroup\$

SH & a friend (date)

The function:

longmonth() {
    date +%B -d"$1 1"
}

Testing it:

$ echo $LANG
de_DE.utf8
$ for i in jan feb mar apr may jun jul aug sep oct nov dec ; do longmonth $i ; done
Januar
Februar
März
April
Mai
Juni
Juli
August
September
Oktober
November
Dezember
$ LANG=C
$ for i in jan feb mar apr may jun jul aug sep oct nov dec ; do longmonth $i ; done
January
February
March
April
May
June
July
August
September
October
November
December

It is short... but calculate it's "evil per character" ratio... mwhuaaahahahaaa...

\$\endgroup\$
3
  • \$\begingroup\$ I don't know the language so I can't see anything evil here. I assume your downvotes are from others in a similar position. Please explain what is going on and why it is evil. I'm curious. \$\endgroup\$ Apr 2, 2014 at 20:22
  • \$\begingroup\$ It's a(n) (ab)use of date's date formatting features. And date respects localisation, it generates the month matching the localisation. -d"a_month_name 1 sets the date to the 1st of the named month (maybe short name) and the missing year is set so it will be the next such month. +%B is the format for prnting the given date and means 'the month's long name'. All tat is wrapped into a shell function and because there is no BASH specific thing in there, SH will be enough to run it. So basically date deserves all the applause, not me! And I don't care about downvotes in codegolf! :-Þ \$\endgroup\$
    – user19214
    Apr 3, 2014 at 4:42
  • \$\begingroup\$ I love this! Abuser. \$\endgroup\$
    – ojblass
    Apr 3, 2014 at 14:35
4
votes
\$\begingroup\$

perl

How about some good ol' brute force?

$|++;

use List::Util qw(reduce);

sub hash {
    my $t=9;
    (reduce { $a*$b*log(++$t+$a) } map { ord() } split//, shift)%54321098
}

my @m = (qw( january february march april may june
             july august september october november december ) );
my %targets = map { hash($m[$_]) => 1 } (0..$#m);

chomp(my $in = lc <>);

print ucfirst $in;

my $r;
if(!$targets{hash($in)}) {
  $r = "a";
  ++$r until $targets{hash($in.$r)};
}
print "$r\n";

Why this is awesome:

  • brute force is always the manliest way to do it.
  • for your convenience, prints the partial answer as soon as it knows it (I bet you didn't know that "Feb" is short for something starting with "Feb..."???)
  • custom hashing function for maximal security.
  • use of perl's built-in operator overloading (increment on strings) makes this code as fast as native C code. Look at all those zeroes, showing just how fast it runs!

    ski@anito:/tmp$ for m in mar apr may jun jul  ; do echo $m | time -f "%U user" perl brute.pl ; done 
    March
    0.00 user
    April
    0.00 user
    May
    0.00 user
    June
    0.00 user
    July
    0.00 user
    
  • The algorithm is intuitively obvious, and I leave a proof as an exercise to the reader, but just to make sure it works in all cases, let's check August, one of the -ber months, and one of the -uaries to make sure we didn't miss anything:

    ski@anito:/tmp$ for m in aug jan oct ; do echo $m | perl brute.pl  ; done 
    August
    January
    October
    

Trollage:

Leaving aside the coding practices that would make Damian Conway die on sight, this code is intermittently wrong, and intermittently extremely slow. "Feb" runs about 6 orders of magnitude - one million times - slower than "may", "jun", or "jul". Feboapic, Sepibnd, Novgpej, and Decabjuj are not months (although they are fun to try to pronounce).

    ski@anito:/tmp$ for m in jan feb mar apr may jun jul aug sep oct nov dec ; do echo $m | time -f "%U user" perl  brute.pl  ; done 
    January
    3.14 user
    Feboapic
    62.77 user
    March
    0.00 user
    April
    0.00 user
    May
    0.00 user
    June
    0.00 user
    July
    0.00 user
    August
    0.10 user
    Sepibnd
    1.33 user
    October
    2.22 user
    Novgpej
    1.11 user
    Decabjuj
    4.27 user

PS - I had some code that has an even greater spread of runtimes, but it boringly outputs the correct answer in all cases, which is much less fun.

\$\endgroup\$
3
votes
\$\begingroup\$

JavaScript - Optimized Node cluster with Branches, Leaves, and string barrels.

// fullMon - Converts month key names to full names using a highly optimized tree for fast traversal.
function fullMon(key) {

    // Initialize the full month string
    var fullMonth = "";

    // Make sure the key is capitalized.
    key = key.substr(0,1).toUpperCase() + key.substr(1).toLowerCase();

    // Set the current node to the tree root.
    var current = fullMon.tree;

    // Traverse the characters in key until we can go no further.
    for (var i = 0; i < key.length; i++) {
        var c = key.charAt(i)
        fullMonth += c
        if (typeof current[c] === "undefined") return key // no full month for this key
        current = current[c]
    }

    // The remaining leaves are the characters in the full month.
    while (current !== null) {
        for (c in current) fullMonth += c
        current=current[c]
    }
    return fullMonth
}

// fullMon.treeBuilder - Builds a character node tree of full month names.
fullMon.treeBuilder = function() {
    // Set a barrel of month keys.
    var barrel = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

    // Root node for letter tree.
    var tree = {};

    // Loop through all month keys.    
    for (var i = 0; i < barrel.length; i++) {

        // Get the next month key and do a barrel roll by
        // splitting into an array of single character strings.
        var monKey = barrel[i].split("");

        // Set the current branch to the tree root.
        var branch = tree;

        // Climb branches in the tree by looping through
        // month key characters and doing leaf wipes.
        for (var c = 0; c < monKey.length; c++) {

            // The next character is the next leaf of the branch.
            var leaf = monKey[c];

            // Wipe this leaf on the branch if it doesn't already exist.
            if (typeof branch[leaf] === "undefined") {
                // If the leaf is the last character then it's not sticky should be set to null.
                branch[leaf] = (c === (monKey.length-1)) ? null : {};
            }

            // Switch to the next branch.
            branch = branch[leaf];
        }
    }
    return tree;
}

fullMon.tree = fullMon.treeBuilder();

fullMon.demo = function () {
    // Demonstrates keys that are not found "none" and found keys.
    var short = ["none","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"];
    for (var i = 0; i < short.length; i++) {
        console.log(fullMon(short[i]));
    }
    // Shows the optimized tree for fast lookups.
    console.log(JSON.stringify(fullMon.tree));
}

fullMon.demo();
\$\endgroup\$
3
votes
\$\begingroup\$

Java, Google and Probability

I am disappointed that so many of the solutions here "reinvent the wheel" when the answer is easily available on the internet.

Here is my program's output:

The short version of jan is january
The short version of feb is february
The short version of mar is margin
The short version of apr is april
The short version of may is mayinhistory
The short version of jun is june
The short version of jul is july
The short version of aug is august
The short version of sep is september
The short version of oct is october
The short version of nov is november
The short version of dec is december

Not perfect, but good enough to send to QA. I was able to achieve these results by leveraging the power of crowdsourcing:

public static String expandMonthName(String shortMonthName) {
    try {
        // First, we ask Google for the answer

        String query = "https://www.google.com/search?q="
                + "what+month+is+" + shortMonthName;
        String response = curl(query);

        // now sift through the results for likely answers.
        // The best way to parse HTML is regex.

        List<String> possibleMonths = new ArrayList<>();
        Pattern pattern = Pattern.compile(shortMonthName + "[A-Za-z]+");
        Matcher matcher = pattern.matcher(response);
        while (matcher.find())
            possibleMonths.add(matcher.group(0));

        // And finally, choose the likeliest answer using 
        // the ineluctable laws of probability

        return possibleMonths.get(new Random().nextInt(possibleMonths.size()));

    } catch (Exception e) { return "August";}   // well, we tried.
}

If it's not clear, expandMonthName("jan") returns a randomly selected word beginning with "jan" from the Google result for "what month is jan". Unless you're behind a proxy, in which case it returns "August."

\$\endgroup\$
2
votes
\$\begingroup\$

Bash + binutils

I tried hard to do the obvious by converting the input to a date object, but failed miserably. Finally I resorted to brute-force approach.

while read -e line; do
  [[ "${line,,}" == "${1,,}"* ]] && o=$line && break
done < <(strings /bin/date)
o=${o:=$1}
o=${o,,}
echo ${o^}

Test runs:

$ bash getmonth.sh jan
January
$ bash getmonth.sh may
May
$ bash getmonth.sh DEC
December
\$\endgroup\$
0
2
votes
\$\begingroup\$

I understand that checking months' names is very hard, and it requires lots of computation and logic thinking. Here's an optimized version of the Buzz-Strahlemann algorythm for checking months' names.

PHP

$month = "Jan"; //Change this to search for a different month, noob :)
$time = time(); //This loads an extended time library
$ivefoundthismonthnowexit = false;
while (!$ivefoundthismonthnowexit) {
    $checkThis = date('F', $time); //"F" stands for "Find it"
    if (substr($checkThis, 1, 4) == $month) $ivefondthismonthnowexit = true; //You can also replace it with ($checkThis, 0, 3)
    //since PHP understands if you are counting from 0 or 1!
    $time++;
}

Trolls:

  • This answer;

  • Doesn't handle timezones and will output a warning message;

  • Doesn't accept month as an input, but you need to hardcode it;

  • Even when you hardcode it, it's case-sensitive;

  • What this code tries to do is to get the current month, get the first three letters, and check if it matches with $month. If it does not match, it increments the timestamp by 1 and then retries. This ends up to be EXTREMELY SLOW;

  • This code outputs nothing (except the warning, of course);

  • Comments are very misleading: time() does not load an extended time library, but gets the current timestamp; substr($checkThis,1,4) skips the first letter of the month and gets the following 4 (arch for March, e.g.); The correct form is the one in the comments;

  • Even when a match is found, the code won't exit the loop: in fact, the variable that gets set to true is different.

\$\endgroup\$
7
  • 3
    \$\begingroup\$ -1: From the code-trolling tag wiki, "The task is to give code that works, but is useless, severely frustrating the OP. " Your code doesn't even work. \$\endgroup\$
    – user12205
    Apr 2, 2014 at 13:04
  • 1
    \$\begingroup\$ Hm? It works and it's useless. Waiting 10 years for an endless loop to finish is not frustrating enough? "It works" means (at least, it means for me), that the code compiles and runs successfully, it doesn't mean that it has to end or give any solution. \$\endgroup\$
    – Vereos
    Apr 2, 2014 at 13:46
  • \$\begingroup\$ @ace (I forgot to mention you in the previous comment); What I'm trying to say in that comment is that I'd like to understand better what do you mean, because it is correct from my point of view. \$\endgroup\$
    – Vereos
    Apr 2, 2014 at 13:47
  • \$\begingroup\$ Perhaps because arch will never equal Mar? \$\endgroup\$
    – user12205
    Apr 2, 2014 at 14:15
  • \$\begingroup\$ So your code cannot convert the month names, therefore it does not work. \$\endgroup\$
    – user12205
    Apr 2, 2014 at 14:22
2
votes
\$\begingroup\$

Batch

What you're asking for is non-trivial. However I have found the perfect solution for you! How this works is by downloading a highly intricate list of the English language to your hard-disk. The input is then checked against the downloaded list and the final name of the month is given! Genius!

Now, this method has many pros over other methods, some being:

  • You can have any abbreviation of the word! E.g. Jan or Janu for January!
  • "You never know when some Pope or President is going to make us switch to another calendar, and then tons of date parsing/formatting code will instantly become worthless!" This is never a problem with our method!
  • The user is sent confirmation prompts, better safe than sorry!

The Code:

@ECHO OFF
setlocal EnableDelayedExpansion
REM Remove this at the end ^^^
REM First off, we have to get the user's input
set /p abbreviatedUserInput= Please input your abbreviated form of the month: 
REM echo out confirmation message. Without this, the thing won't work
SET /P variableThatIsUsedForConfirmation= Are you sure you want to look for %abbreviatedUserInput% (Y/N)? 
REM if the user said no, send him elsewhere
if /i {%variableThatIsUsedForConfirmation%}=={n} (goto :hell)
REM to keep things clean, we clear the screen!
cls
ECHO Prepare for launch!
REM make sure the user reads what we wrote, we spent time on this and the user must understand that... 
REM BTW this pings an incorrect ip address and waits 3000 millisex for the output
ping 1.1.1.1 -n 1 -w 3000 > nul
REM to keep things clean, we clear the screen!
cls
REM We must inform the user that something is going on, otherwise they might get bored and quit the app
ECHO LOA-DING!
REM Now, how this works is by utilizing the dictionary.. I believe we all know what that is. First of all, let's get a dictionary!
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://www.mieliestronk.com/corncob_caps.txt', 'dic.txt')"
REM to keep things clean, we clear the screen!
cls
REM The user probably already got bored, let's inform them that we're still working...
ECHO STILL WORKING...
REM wait what?!! The dictionary is all caps!! Lets fix that...
REM Lets loop through the file like so:

for /F "tokens=*" %%A in (dic.txt) do (
    SET "line=%%A"
    REM replace ALL the letters!!
    SET "line=!line:A=a!"
    SET "line=!line:B=b!"
    SET "line=!line:C=c!"
    SET "line=!line:D=d!"
    SET "line=!line:E=e!"
    SET "line=!line:F=f!"
    SET "line=!line:G=g!"
    SET "line=!line:H=h!"
    SET "line=!line:I=i!"
    SET "line=!line:J=j!"
    SET "line=!line:K=k!"
    SET "line=!line:L=l!"
    SET "line=!line:M=m!"
    SET "line=!line:N=n!"
    SET "line=!line:O=o!"
    SET "line=!line:P=p!"
    SET "line=!line:Q=q!"
    SET "line=!line:R=r!"
    SET "line=!line:S=s!"
    SET "line=!line:T=t!"
    SET "line=!line:U=u!"
    SET "line=!line:V=v!"
    SET "line=!line:W=w!"
    SET "line=!line:X=x!"
    SET "line=!line:Y=y!"
    SET "line=!line:Z=z!"
    ECHO !line! >> dic-tmp.txt
)

REM to keep things clean, we clear the screen!
cls
REM The user probably already got bored, let's inform them that we're still working...
:lookup
ECHO WOW! THAT TOOK LONG! ALMOST THERE...
REM Alright, now we need to find the correct date in the dictionary, we might need the users help in this...
REM Lets loop through ALL the lines again
set match=seriously?
for /F "tokens=*" %%a in (dic-tmp.txt) do (
    SET "line=%%a"
    REM to keep things clean, we clear the screen!
    cls
    REM replace the user input with some other stuff...
    SET "test=!line:%abbreviatedUserInput%=lol!"
    REM if the original line does not equal the test variable, then we have a match!
    IF NOT !line!==!test! (
        REM ask the user if the match is correct..
        set /P variableThatIsUsedForConfirmation= "Did you mean !line!? (Y/N): "
        REM if the user entered "y"
        IF /i {!variableThatIsUsedForConfirmation!}=={y} (
            REM set the variable "match" to the current line and goto the matchFound section...
            set match=!line!
            goto :matchFound
        )
    )
)
:matchFound
REM to keep things clean, we clear the screen!
cls
REM give the user their match
Echo Here's your month's full name: %match%
PAUSE
:hell
ECHO screw you!

Trollz

- Batch... - Downloading a list of words, because we can't type out the months manually... - Not using switch case hack - VERY SLOW - converting the text file to lowercase and saving it in another file - run it a second time without deleting the text files created and it will be even slower - Something ticks the script off while converting the dic.txt file to lowercase, this sets echo back on - This spoiler thing has messed up formatting by the way...

\$\endgroup\$
2
votes
\$\begingroup\$

! #/bash

! #/bash

# Make the MONTH variable equal to the $1 variable
MONTH="$1"

# Run grep passing the $MONTH variable and the -i flag
# Then use the << operator followed by a list of months
grep -i "$MONTH" << January
March
May
July
August
0ctober
December
April
June                                      
September
November
February
January

To make your program respond faster, I have put the months with 31 days earlier in the list. Statistically speaking, given an even distribution of dates, you are more likely to be in one of those months.

I documented each line to impress your boss.

Save this in a file called lookup_month_script.bash and copy-paste the following line to test it:

bash $PWD/lookup_month_script.bash "0ct"

Good luck with your project!


- Doesn't work for January, despite it being listed twice. (We are actually using January as the delimiter for the start and end of the heredoc.)

- Also doesn't work for October. Nobody can see why.

- If the input happens to be empty, returns all 11 months.

- If the script is copy-pasted, the June response will be 42 characters in length.

Minor:

- The shebang is somewhat incorrect, but no warning is given.

- Comments that are comments which say what the line below them is saying.

- Even if the program did respond sooner for the earlier entries, it still wouldn't complete any faster.

\$\endgroup\$
1
vote
\$\begingroup\$

JavaScript - 209

It does say not to convert to a Date, which is not what's happening here, I'm simply using Date to generate the extension of the short name.

function m(s){c=s.charAt(0).toUpperCase()+s.substr(1).toLowerCase();a="ember,ember,ober,tember,ust,y,e,,il,ch,uary,uary".split(",");b=[];for(i=12;i--;)b[(""+new Date(1,i,1)).slice(4,7)]=11-i;return c+a[b[c]];}

Tests Input/Output:

jan: January
feb: Febuary
mar: March
apr: April
may: May
Jun: June
JUL: July
AuG: August
sEp: September
OCT: October
nov: November
dec: December
\$\endgroup\$
4
  • 3
    \$\begingroup\$ I also appear to have trolled Febuary - r :) On purpose, of course... \$\endgroup\$
    – Matt
    Apr 2, 2014 at 6:25
  • \$\begingroup\$ Sounds like somebody's got a case of the Wendsdays. \$\endgroup\$
    – Jason C
    Apr 2, 2014 at 6:54
  • 5
    \$\begingroup\$ @Matt Don't you mean "On pupose"? \$\endgroup\$
    – Justin
    Apr 2, 2014 at 7:22
  • \$\begingroup\$ Of couse @Quincunx \$\endgroup\$
    – Matt
    Apr 2, 2014 at 8:51
1
vote
\$\begingroup\$

Java 696 including test input

public class DateConverter {
    String months[] = 
    {
        "January", "February","March","April","May","June","July",
        "August","September","October","November","December"
    };
    DateConverter(){}
    String LongMonth(String shortMonth)
    {
        String m = "Invalid";
        for(int i=0;i<months.length;i++)
        {
            if(months[i].toLowerCase().contains(shortMonth.toLowerCase()))
            {
                m=months[i];
                break;
            }
        }
        return m;
    }

    public static void main(String[] args) {

        String input[] = {"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
        for(int i=0; i<input.length; i++)
        {
            System.out.println((new DateConverter()).LongMonth(input[i]));
        }
    }
}
\$\endgroup\$
1
vote
\$\begingroup\$

The programming language "Brainf*ck" is a perfect tool for this! It might not be exactly what you were looking for, sure, but it gets the job done flawlessly!

>+<+[>[>[-]+<-]>[<+>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<->-]>>>>>>>>>>>>>>>>>>>>>
[<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+

This is the debug part of the code used when looping more than once

>>+++++++++++++++[>+++++>+++++++>++>+++++++>+++<<
<<<-]>--.>+++++.++.+++++.-.>++.<.>>-.---.<.<.>>+++.<<--.>>---..>.<<<------.>>.
<<++++++++..>>.<<--.>.>----.+..<<.>>+++.<<++++.>>++++.--------
.<<--.>>++++++++.<<-----.-.>+.>>[-]<[-]<[-]<[-]<[-]<++++++++++.[-]

It takes a dummy argument due to the nature of my interpreter 
If you're using some other intepreter I can rewrite the code for you

>>>>>>>>>>>>>>>>>>>>>>>,<+<<<<<<<<<<<<<<<<<<<<<<<<->-]>>>>>>>>>>>>>>>>>
[<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+

This is the normal part of the code, used when starting the programme the first time

>>+++++++++++++++[>+++++>+++++++>++>+++++++>+++<<<<<-]>--.>
+++++.++.+++++.-.>++.<.>>-.---.<.<.>>+++.<<--.>>---..>.<<<------.>>.<<++++++++..>>.<<-
-.>.>----.+..<<.>>+++.<<++++.>>++++.--------.<<--.>>++
++++++.<<-----.-.>+.>>[-]<[-]<[-]<[-]<[-]<++++++++++.[-]<-]>>>>>>>>>>>>>>>>>>>>>>>
[<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>-]<<<<<<
<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+

Here we take three arguments and assign them to variables; This is the three-letter 
abbreviation of the month

>>>>>>>>>>>>>>,<,<,

Now we check if the abbreviation is good; note that it will fail if it doesn't begin 
with a capital letter and isn't followed by two lowercase letters
In general it will print an error message and wait for you to input a letter 
(or just hit enter) before it exits

<<<[-]>>>>>[<<<<<+<<<<<<<+>>>>>>>>>>>>-]<<<<<<<<<<<<[>>>>>>>>>>>>+<<<<<<<
<<<<<-]>>>>>>>----------------------------------------------------------------->[-]    
<[<<<+>>>-]->[<<<<<<<+>+<<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+<<
<<<<<<-]>>[>>[<+<<<+>>>>-]<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>-]>>
[>>>+<<<[-]]<<<[-]<->>>>>>>[<<<<<<<->>>>>>>-]<<<<<<<[>
>>>>>>+<<<<<<<-]>>>>>>>[>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]
<[>[-]+<-]>[<+>>+++++++++++[>++++++>++++++++++>+++<<<-
]>+++.>++++..---.+++.>.[-]<[-]<[-]<++++++++++.[-]>>>>>>>>>>>>>>>,,<<<<<<<<<<<<<<<<<-<-
>>-]>>>>>>>>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<<<<<<<<+>>>
>>>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>>>>>>>>[-]>>>>[<<<<+    
<<<<<<<+>>>>>>>>>>>-]<<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>
>>>>>-------------------------------->[-    
]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<[<<<+>>>-]>    
[<<<<<<<+>+<<+>>>>>>>>
-]<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>[>>[<+<<<+>>>>-]<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]
<<<[>>[-]+<<-]>>-]<[>>>>>>-<<<<<<[-]]>>>[-]>>>>[-]>>
>[<<<+<<<<<<<<+>>>>>>>>>>>-]<<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>>>>>>>---------------
----------------->[-]+++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<[<<<<+>>>>-]>[<<<<<<<<+>+
<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>>[>>[<+<<
<+>>>>-]<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>-]>>[>>>>-<<<<[-]]<<<[-
]>>>>>>[<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>>-<<<<<<<[-]]>
>>>>>>>[<<<<<<<<+>+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]<[>>>>>>>[-]-<<<<<<<[-]]->>>>>>>
[<<<<<<<->>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[>>>>
>>>>>>+<<<<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[<+>>+++++++++++
[>++++++>++++++++++>+++<<<-]>+++.>++++..---.+++.>.[-]<[-]<[-]<+
+++++++++.[-]>>>>>>>>>>>>>>>,,<<<<<<<<<<<<<<<<<-<->>-]>>>>>>>>>>>>>>>>>>
[<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<<[>[-]+<
-]>[<+>>>>>>>>>[-]>>>[<<<+<<<<<<<+>>>>>>>>>>-]<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-]>>>>>>>-    
------------------------------->[-]+++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++<[<<<+>>>-]>[<<<<<<<+>+<<+>>>>>>>>-]
<<<<<<<<[>>>>>>>>+<<<<<<<<-]>>[>>[<+<<<+>>>>-]<<<<[>>>>+
<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>-]<[>>>>>>-<<<<<<[-]]>>>[-]>>>>[-]>>[<<+
<<<<<<<<+>>>>>>>>>>-]<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-
]>>>>>>>>-------------------------------->[-
]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<[<<<
<+>>>>-]>[<<<<<<<<+>+<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>>[>>[<+<<<+>>>>-]
<<<<[>>>>+<<<<-]+>>>[<<->>>-<<<<->>>[-]]<<<[>>[-]+<<-]>>
-]>>[>>>>-<<<<[-]]<<<[-]>>>>>>[<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>>-<<<<<<<[-]]>>>>>>>>
[<<<<<<<<+>+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]<[>>>>>>>[-
]-<<<<<<<[-]]->>>>>>>[<<<<<<<->>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[>>>>>>>>>>>+
<<<<<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[
<+>>+++++++++++[>++++++>++++++++++>+++<<<-]>+++.>++++..---.+++.>.[-]<[-]<[-]<++++++++++.    
[-]>>>>>>>>>>>>>>>,,<<<<<<<<<<<<<<<<<-<->>-]>>>>>>>>
>>>>>>>>>>>[<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+

This part of the code handles special exceptions to the pattern

>>>>>>>>>[-]>>>>>[<<<<<+<<<<<<<+>>>>>>>>>>>>-]<<<<<<<<<<<<[>>>>>>>>>>>>+<<<<<<<<<<<<-
]>>>>>>>>[-]++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++<[<<<<<<+>>>>>>-]->[<<<<<<<-<+>>>>>>>>-]    
<<<<<<<<[>>>>>>>>+<<<<<<<<-]>[>>>>>>+<<<<<<[-]]>>>>>>>[-]>
>>[<<<+<<<<<<<<+>>>>>>>>>>>-]<<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>>>>>>>>[-    
]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++<[<<<<<<<+>>>>>>>-]->[<<<<<<<<-<+>>>>>>>>>-]
<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>[>>>>>>>+<<<<<<<[-]]>>>>>>[<<
<<<<<+>>>>>>>-]<<<<<<<[[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]
<[>>>>>>>-<<<<<<<[-]]]>>>>>>>>[-]>>[<<+<<<<<<<<+>>>>>>>>>>-]
<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-]>>>>>>>>>[-
]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++<[<<<<<<<+>>>>>>>-]->[<<<<<<<<-<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+
<<<<<<<<<-]>[>>>>>>>+<<<<<<<[-]]>>>>>>[<<<<<<<+>>>>>>>-]<<<<
<<<[[-]>>>>>>>>[<<<<<<<<+>+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]<[>>>>>>>-<<<<<<<[-]]]-
>>>>>>>[<<<<<<<->>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>
>[>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[<+>>++++++++++++
[>++++++>++++++++>+++++++++<<<-]>++.>+.>++.+++++++.<
.>---.+++++++.[-]<[-]<[-]<++++++++++.[-]>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<->-
]>>>>>>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>-
]<<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+

This part of the code handles the regular pattern

>>>>>>>>>[-]>>>>>[<<<<<+<<<<<<<+>>>>>>>>>>>>-]<<<<<<<<<<
<<[>>>>>>>>>>>>+<<<<<<<<<<<<-]>>>>>>>.[-]>>>>[<<<<+<<<<<<<+>>>>>>>>>>>-]       
<<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>>>>>>.[-]>>>[<<<+<<<<<<<+>>>>
>>>>>>-]<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-]>>>>>>>.<<<<<<<++++++++++++
[>++++++++++>++++++++<<-]>---.>+.<---.+++++++.>[-]<[-]<++++++++++.[-]>>
>>>>>>>>>>>>+<<<<<<<<<<<<<<<<->-]<[>[-]+<-]>[<+

Here the programme checks if you want to insert another abbreviation or are done with the programme

>-]>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<[>[-]+<-]>
[<+>>+++++++++++++++[>+++++>++++++++>++>+++++++>++++>+
+++++<<<<<<-]>--.>-----.>++.<+.>>-.-------.<<.>.>.<<--------..>>>+++.<<.>>>+.--.
<<<+++++++++++++++.<<+++++.>>>----.>>[-]<[-]<[-]<[-]<[-]<[-]
<++++++++++.[-]>>>>>>>>>>>>>>>>>>>>>>>,<<<<<<<<<<,<<<<<<[-]>>>>>>[<<<<<<+
<<<<<<<+>>>>>>>>>>>>>-]<<<<<<<<<<<<<[>>>>>>>>>>>>>+<<<<<<<<<<<<<-]>
>>>>>>>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<[<<<<<<+>>>>>>-]->[<<<<<<<-<+>>>>>>>>-]<<<<<<<<[>>>
>>>>>+<<<<<<<<-]>[>>>>>>+<<<<<<[-]]>>>>>>[>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>
[-]]<<<<<<<<-]<[>[-]+<-]>[<+>>>>>>>>>[-]>>>>>>[<<<<<
<+<<<<<<<+>>>>>>>>>>>>>-]<<<<<<<<<<<<<[>>>>>>>>>>>>>+<<<<<<<<<<<<<-]>>>>>>>>[-
]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++<[<<<<<<+>>>>>>-]->[<<<<<<<-<+>>>>>>>>-]<<<<<<<<[>>>>>>>>+
<<<<<<<<-]>[>>>>>>+<<<<<<[-]]<->>>>>>>[<<<<<<<->>>>>>>
-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>[>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<-
>>>>>>>>>[-]]<<<<<<<<-]<[>[-]+<-]>[<+-<->>-]>>>>>>>>>>>>>>>>
>>>>>>>>>[<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>-]
<<<<<<<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>+++++++++++[>++++++>++++++++++>+++
<<<-]>+++.>++++..---.+++.>.[-]<[-]<[-]<++++++++++.[-]<<<->>-]<<]

I'm sure your teacher will be proud when you show him this!


Trolling

The programme is, first of all, quite badly written. I've made some loops that cause random error prints and general non-workingness for lack of a better word. It takes a bit of cleanup to get decently working code (primarily in the first two paragraphs of it) which is anyhow useless as it gives long names as "abbreviation + 'uary'" (January, Febuary, Maruary etc.) The programme also includes redundant code for "January" (defined as an exception and coded separately). First answer on Stackexchange, so I hope this meets criteria

\$\endgroup\$
1
vote
\$\begingroup\$

Java

Dear Computer Scientist Apprentice,

This is quite a difficult task, and I have solved only partially: I guess this is for your thesis work or some research purpose.

Up to now I have only beta version with some minor bugs: sometimes it gives the wrong results, but I'm sure your professor will accept your effort.

file Month.java:

/**
 * This bean keep track of a month-code (e.g. Apr) and month-name (e.g. April)
 * pair.
 */
public class Month{
    String month_name;
    String month_code;
    public void Month(monthName,monthCode){
        setMonthName(monthName);
        setMonthCode(monthCode);
    }
    public String getMonthName(){
        return this.monthName;
    }
    public void setMonthName(String monthName){
        this.monthName=monthName;
    }
    public String getMonthCode(){
        return this.monthCode;
    }
    public void setMonthCode(String monthCode){
        this.monthCode=monthCode;
    }

file Era.java:

/**
 * This bean keep contains every couple of month-code,month-name in a year.
 */
public class Era{
    List <Month>months;
    public void Era(){
        months.add(new Month("Jan","January"));
        months.add(new Month("Feb","Febrary"));
        months.add(new Month("Apr","March"));
        months.add(new Month("May","May"));
        months.add(new Month("June","June"));
        months.add(new Month("Jul","July"));
        months.add(new Month("Aug","August"));
        months.add(new Month("Sep","September"));
        months.add(new Month("Oct","October"));
        months.add(new Month("Nov","Novemeber"));
        months.add(new Month("Dec","December"));
   }
   public String getMonthByCode(String monthName){

       return String.format("[%s]",months.get(new Random().nextInt((11) + 1) + 0));
   }
   public static void main(String ... argv){
        String monthCode="jan";
       System.out.println(String.format("%s: %s",monthCode, new Era().getMonthByCode(monthCode));
   }

To run it execute:

javac Month.java
javac Era.java
java Era jan

output:

jan: [January]

Remember to set your %JAVAPATH% to the path where your Java compiler is installed!

It just return a random month. Actually I didn't even test it. I guess some imports are missing.

\$\endgroup\$
1
vote
\$\begingroup\$

Since the OP is using Java, I'll give a Java solution. The idea is simple:

  1. Create a Map from long name to short name.
  2. Generate a random String, map it to the short name.
  3. Use String.equalsIgnoreCase to check whether the short name is same as the input short name ignoring cases. If so, success, exit.
  4. Otherwise go to Step 2.

Here is the source:

import java.util.*;

public class Short2Long {
    static final Map<String, String> long2Short = new HashMap<String, String>();
    static {
        long2Short.put("Janurary", "jan");
        long2Short.put("February", "feb");
        long2Short.put("March", "mar");
        long2Short.put("April", "apr");
        long2Short.put("May", "may");
        long2Short.put("June", "jun");
        long2Short.put("July", "jul");
        long2Short.put("August", "aug");
        long2Short.put("September", "sep");
        long2Short.put("October", "oct");
        long2Short.put("November", "nov");
        long2Short.put("December", "dec");
    }

    static Random rand = new Random();

    static String genString() {
        int len = rand.nextInt(9-3) + 3;
        StringBuffer res = new StringBuffer(len);
        res.append((char)('A' + rand.nextInt(26)));
        for (int i = 1; i < len; i ++) {
            res.append((char)('a' + rand.nextInt(26)));
        }
        return res.toString();
    }

    public static void main(String[] args) {
        String s = args[0];
        while (true) {
            String l = genString();
            if (s.equalsIgnoreCase(long2Short.get(l))) {
                System.out.println(s + " -> " + l);
                break;
            }
        }
    }
}

Trolling

The program needs a fast CPU and your patient. When you learn multi-threading and have a multi-core cpu, you can try make it faster.

\$\endgroup\$
1
vote
\$\begingroup\$


Thank you for posting this thought provoking and original question. Those of us that post answers on Stack Overflow enjoy the opportunity to help posters, as the purpose of this website is to catalogue all such questions to make the need for text books and self-motivated learning obsolete. Do not be alarmed by your lack of understanding of this particular question, as it is a common type of question asked because of its hidden trick required to solve it effectively. Instructors will commonly ask this question to determine not only your depth of understanding of the language, but also whether you where aware of this common programmer pitfall: character encoding. You will understand more completely after you thoroughly read through the following link, as I know you will: link.

I am sure by now that your professor has described in great detail the importance of code reuse, so as you have read the character encoding link that I provided, you are absolutely coming to the understanding that you will have to make a generic enough class that can handle any language, even if the original question didn't specifically specify this requirement (you may also want to learn about requirement specification, which will help you understand requirements, read through this link: link.

You where very intelligent in suggesting not use the provided Date object, as using the code in the default languages will not allow you to show your true understanding of the language to your professor.

To help you through this difficult question, I have written a Groovy application that will solve you problem, and will undoubtably make more sense than that cryptic java. Don't be alarmed at the use of Groovy for this answer, as Groovy also runs on the JVM just like Java code, so you can easily drop this code into your java class with only a few modifications. I have attached a link to help you through this process, but I wouldn't worry about it until the morning, as it should only take a second (here is the link for later: link. So, just copy the code for now, as I will show plenty of test cases of the code working appropriately, so that you can feel confident in your submission. I definitely understand that you are very very busy eager student, with plenty of obligations on your plate. You are probably aware that contributors here work full time, and are well compensated.

//Definetely leave the comments in so your instructor
//can see how well you document your code!

//see how easy it is to specify other languages!
//the users of your software will probably have an IDE just
//like yours, so they can easily come into the source
//code and edit these to their liking, That's Code Reuse!
def EnglishNames ="""January
February
March
April
May
June
July
August
October
November
December
"""

//change this to use other encodings, as discussed above
final String encodingToUseSoThatOurCodeIsSuperRobust = "UTF-8"

//it is a good idea to number your lists for clarity,
//just in case you need more
def list1 = []
def list2 = []

//specifying the method name like this will help make it
//easy to add more languages, another method for another
//language

//this is called a 'Closure', which is pretty much identical
//to that cool new Java thing called the 'Lambda', so if you
//wanted to turn this into Java code, it would be soo easy!
EnglishNames.eachLine() {
    //You probably remember you instructor telling you
    //never to do this String 1 == String 2
    //So to get around that, we will convert the String
    //to bytes, Easy huh!
    list1.add(it.getBytes(encodingToUseSoThatOurCodeIsSuperRobust))
}

//change this to run a different test, the IDE no doubt makes
//it very easy to do this!
//See the very very descriptive variable name for readability?
def iAmLookingForThisCountriesLongNameWithThisShortName = "Dec"
def theFoundAnswerInTheListIs

//this is the real important part as you can easily see
for(BigInteger index = 0; index < list1.size(); index ++){
    for(BigInteger indeX = 0; indeX < list1[index].size(); indeX ++){
        list2[index] = [list1[index][0],list1[index][1],list1[index][2]]
    }
}

boolean foundTheAnswerSoDontDoAnymore = false

//now we just find the correct answer in the list!
for(BigInteger index = 0; index < list1.size(); index ++){
    for(BigInteger indeX = 0; indeX < list1[index].size(); indeX ++){
        //see how readable the following code is!
        if((list2.get(index)) == iAmLookingForThisCountriesLongNameWithThisShortName.getBytes(encodingToUseSoThatOurCodeIsSuperRobust)){
            //see how we can now use the == so we can compare the two strings!
            if(!(new Boolean(foundTheAnswerSoDontDoAnymore))){
                println new String(list1[index], encodingToUseSoThatOurCodeIsSuperRobust)
                foundTheAnswerSoDontDoAnymore = true
            }
        }
    }
}

Sorry that I didn't leave anything for you to do here, I got carried away answering your thought provoking question. So just copy and paste this response. As you can see from the following runs of the code, here is what it can do:

input: Dec, output: December
input: Jan, output: January
input: Feb, output: February
\$\endgroup\$
1
vote
\$\begingroup\$

Julia

You're going to want to use the power of multiple dispatch here. First we'll define a type of each month. Then we can write simple function definitions for each month type that give the desired answer. This will allows you to use the convenient form of nicename(Jan) without having to bother with those annoying quotation marks. Plus we can define a convenience function to accept strings and converting them to types, reuse all the work we already did to provide a totally new interface.

abstract Month
abstract Jan <: Month
abstract Feb <: Month
abstract Mar <: Month
abstract Apr <: Month
abstract May <: Month
abstract Jun <: Month
abstract Jul <: Month
abstract Aug <: Month
abstract Sep <: Month
abstract Oct <: Month
abstract Nov <: Month
abstract Dec <: Month
nicename(::Type{Jan})="January"
nicename(::Type{Feb})="February"
nicename(::Type{Mar})="March"
nicename(::Type{Apr})="April"
nicename(::Type{May})="May"
nicename(::Type{Jun})="June"
nicename(::Type{Jul})="July"
nicename(::Type{Aug})="August"
nicename(::Type{Sep})="September"
nicename(::Type{Oct})="October"
nicename(::Type{Nov})="Novermber"
nicename(::Type{Dec})="December"

nicename(s::String)=nicename(eval(symbol(ucfirst(s))))



nicename(Jan)
nicename("jan")
\$\endgroup\$
2
  • \$\begingroup\$ What language is it? \$\endgroup\$
    – ugoren
    Apr 9, 2014 at 4:57
  • \$\begingroup\$ Julia, silly thing to leave out. \$\endgroup\$
    – gggg
    Apr 10, 2014 at 16:52
0
votes
\$\begingroup\$

Python 2.75

def getMonthName(short):
    from time import time, gmtime, strftime
    time = time()
    while not (lambda t:strftime("%B",t).upper().startswith(short.upper()))(gmtime(time)): time += 1
    return strftime("%B",gmtime(time))

True beauty is in simplicity, which means low memory requirements. Forget those pesky dictionaries and paragraphs of code. This function is so good, it will match short month names using any case. Observe.

>>> getMonthName("Apr")
'April'
>>> getMonthName("apr")
'April'
>>> getMonthName("APR")
'April'

BONUS:

You can use more than the first 3 characters (e.g. "sept", "febr", etc.)

This will loop through every second from the time you run this code, checking for match at the beginning of the name, so it will take forever to run if the expected result is not your current month. Also numerous style errors.

\$\endgroup\$
0
votes
\$\begingroup\$

in c#

 var Dictonery = "january,febuary,March,April,May,June,July,August,September,October,November,December";
                     var input = "jan";
                     var outpt= Regex.Match(Dictonery , input + "[a-z]*",
RegexOptions.IgnoreCase).Value;
\$\endgroup\$
0
votes
\$\begingroup\$

Here's a little program that does what you requested.

Or actually, 13 of them.

I've written it in C++ because that's what I use at the moment, but it converts pretty easily to Java. Being a dedicated student, I'm sure you can work that bit out yourself.

#include <iostream>
#include <fstream>
#include <cstdlib>

int main()
{
   std::string months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

   for(int i = 0; i <= 12; ++i)
   {
       std::string filename = months[i] + ".cpp";
       std::ofstream myfile;
       myfile.open( filename.c_str() );
       myfile << "#include <iostream>\n\nint main()\n{\n\tstd::cout << \"" << months[i] << "\" << std::endl;\n return " << i << ";\n}";
       myfile.close();

       std::string compile = "g++ " + months[i] + ".cpp -o " +  months[i].substr(0, 3);
       system( compile.c_str() );
   }

   system("Dec");

   return 0;
}

Oh and I may have overlooked a little offset error in the loop.

I decided to be nice and use std::strings instead of char*s. I'm sure I would have confused you with syntax like char*[] and I would definitely have forgotten to call delete, or done something stupid like call delete instead of delete[].

\$\endgroup\$
0
0
votes
\$\begingroup\$

C

Some kind of generic transformation of abbreviations to full words, just adjust data array...

#include <stdio.h>
#include <string.h>
#include <stdint.h>

const char* getLong(char *shrt) {
    size_t position;
    size_t found = 0;
    static int32_t data[19];

    data[000] = 0x756e614a;
    data[001] = 0x46797261;
    data[002] = 0x75726265;
    data[003] = 0x4d797261;
    data[004] = 0x68637261;
    data[005] = 0x69727041;
    data[006] = 0x79614d6c;
    data[007] = 0x656e754a;
    data[010] = 0x796c754a;
    data[011] = 0x75677541;
    data[012] = 0x65537473;
    data[013] = 0x6d657470;
    data[014] = 0x4f726562;
    data[015] = 0x626f7463;
    data[016] = 0x6f4e7265;
    data[017] = 0x626d6576;
    data[020] = 0x65447265;
    data[021] = 0x626d6563;
    data[022] = 0x00597265;

    for (position = 0; position < strlen(shrt); position++) {
        shrt[position] = position < 1 ? (shrt[position] >= 97 ?
        shrt[position] - 97 + 65 : shrt[position]) : (
        shrt[position] <= 90 ? shrt[position] - 90 + 122 : shrt[position]);
    }

    for (position = 0; position < strlen(((char*)data)); position++) {
        if (((char*)data)[position] == shrt[found]) {
            found++;
            if (found == strlen(shrt)) {
                found = position;
                position -= strlen(shrt);
                for (;((char*)data)[found] > 90; found++);
                ((char*)data)[found] = 0;
                return &(((char*)data)[position + 1]);
            }
        } else {
            found = data[0] - data[1] - 0x2EF4EEE9;
        }
    }
    return "not a month";
}

int main(int argc, char *argv[]) {
    if (argc != 2) return 1;
    printf("%s is %s\n", argv[1], getLong(argv[1]));
    return 0;
}
\$\endgroup\$
0
votes
\$\begingroup\$

PHP

$month = strtolower($month);
if($month = 'jan') {
return 'January';
}
if($month = 'feb') {
return 'February';
}
if($month = 'mar') {
return 'March';
}
if($month = 'apr') {
return 'April';
}
if($month = 'may') {
return 'May';
}
if($month = 'jun') {
return 'June';
}
if($month = 'jul') {
return 'July';
}
if($month = 'aug') {
return 'August';
}
if($month = 'sep') {
return 'September';
}
if($month = 'oct') {
return 'October';
}
if($month = 'nov') {
return 'November';
}
if($month = 'dec') {
return 'December';
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.