text:
Decimal concatenation of squares
Premise
One night, I was just contemplating on numbers. I found out about something unique about numbers like 7, 10, 12, 13, and more. They are squares of squares! Meaning, that when squared, are comprised of squares themselves. The OEIS calls them Squares which are a decimal concatenation of two or more squares.
Examples of such numbers include 7 (49 has 22 and 32) 13 (169 has 42 and 32) and 20 (400 has 22 and 02). Other examples include 37, as 1369 is a term as it can be partitioned as 1, 36 and 9. 1444 (382) is a term as it can be partitioned as 1, 4, 4, 4. I asked about this on Math.SE, and it was named after me!
Challenge
Design a program that prints TanMath numbers.  Given the number n (starting at 1), print the nth TanMath number, T(n).
As a code example:
>> 1
>> 7

or
>> 4
>> 13

Reference Python implementation(thanks @MartinBüttner and @Sp3000!):
from math import sqrt

n = input()

def r(digits, depth):
    z = len(digits)
    if z < 1:
        return (depth > 1)
    else:
        for i in range(1, z+1):
            t = int(digits[:i])
            if sqrt(t).is_integer() and r(digits[i:], depth+1):
                return True
        return False

i=0
t=0
while t < n:
    i += 1

    if r(str(i**2), 0):
        t += 1

print i

Here is a list of the first 100 numbers:

7 10 12 13 19 20 21 30 35 37 38 40 41
  44 50 57 60 65 70 80 90 95 97 100 102 105 107 108 110 112 119 120 121
  125 129 130 138 140 150 160 170 180 190 191 200 201 204 205 209 210
  212 220 223 230 240 250 253 260 270 280 285 290 300 305 306 310 315
  320 325 330 340 342 343 345 348 350 360 369 370 375 379 380 390 397
  400 402 405 408 410 413 420 430 440 441 450 460 470 475 480 487

This is a code golf, so the shortest code wins!
Good luck!

38² can also be written 12² & 2² of course.

@Neil yes...cIt is in the list of the first 100 numbers.

Sorry if I've confused you, but I was just commenting on your choice of decomposition of 38² as 1² & 2² & 2² & 2².

@Neil oh.. I see. I will leave it like that for now, I think it is obvioud to others that 12^2 can be included in the decomposition.

Pyth, 23 21 20 bytes
e.ff!-sMT^R2Z./`^Z2Q

Thanks to @isaacg for golfing off 1 byte!
Try it online.
How it works
                      (implicit) Store the evaluated input in Q.
 .f                Q  Filter; find the first Q positive integers Z such that:
                ^Z2     Compute the square of Z.
               `        Cast to string.
             ./         Compute all partitions of the string.
   f                    Filter; find all partitions T such that:
      sMT                 Cast all elements of T to integer.
         ^R2Z             Compute the squares of all integers in [0, ..., Z-1].
     -                    Remove the squares from the integers in T.
    !                     Compute the logical NOT of the result. This returns True
                          iff all integers in T are squares of numbers less than Z.
                        Keep T if `!' returned True.
                      Keep Z if `!' returned True for at least one T.
e                     Retrieve the last of the Q matches.

Run time complexity is catastrophic. I don't recommend trying inputs over 60 with the online interpreter.

The t is unnecessary, because ^R2Z will not contain ^Z2. It's the same as Python's range, it doesn't include the top end.

Yes, I realized that as soon as I read your answer. That was a leftover from the previous approach... Thanks!

I actually wrote that before I saw your post, my internet is very slow and I didn't see your update until after I posted. Not trying to snipe you or anything.

No worries. I assumed it was something like that. You have helped me many times before. (And I'm intimately familiar with the problem of slow internet. :P)

Julia, 189 145 bytes
n->(c=m=0;while c<n m+=1;d=["$(m^2)"...];for p=partitions(d) d==[p...;]&&!any(√map(parse,map(join,p))%1.>0)&&endof(p)>1&&(c+=1;break)end;end;m)

This creates an unnamed function that accepts an integer and returns an integer. To call it, give it a name, e.g. f=n->....
Ungolfed:
function tanmath(n::Integer)
    # Initialize the number to check (c) and the nth TanMath
    # number (m) both to 0
    c = m = 0

    # While we've generated fewer than n TanMath numbers...
    while c < n
        # Increment the TanMath number
        m += 1

        # Get the digits of m^2 as characters
        d = ["$(m^2)"...]

        # Loop over the unordered partitions of the digits
        for p in partitions(d)
            # Convert the partition of digits to parsed numbers
            x = map(parse, map(join, p))

            # If the partition is in the correct order, none of the
            # square roots of the digits are non-integral, and p is
            # of length > 1...
            if d == [p...;] && !any(sqrt(x) % 1 .> 0) && endof(p) > 1
                # Increment the check
                c += 1

                # Leave the loop
                break
            end
        end
    end

    # Return the nth TanMath number
    return m
end

Thanks to Dennis for some help and ideas and thanks to Glen O for saving 44 bytes!

JavaScript ES6, 126 127
The reference implementation, converted to Javascript with some golf trick.
Using eval to avoid explicit return.
Test running the snippet below in an EcmaScript 6 compliant browser, with spread operator, default parameters and arrow functions (I use Firefox)

F=n=>eval('for(i=t=0;t<n;t+=k([...i*i+""]))++i',k=(s,l=1,n="")=>s[0]?s.some((d,i)=>Math.sqrt(n+=d)%1?0:k(s.slice(i+1),l-1)):l)

// Less golfed

U=n=>{
  k = (s,l=1,n="") =>
    s[0]
    ? s.some((d,i) =>
             Math.sqrt(n+=d)%1 ? 0 : k(s.slice(i+1),l-1)
            )
    : l;
  for(i=t=0; t<n; ) {
    ++i;
    t += k([...i*i+""])
  }
  return i
}

function test() { R.innerHTML=F(+I.value) }

test()
<input id=I value=100><button onclick='test()'>-></button>

JavaScript (ES6), 143 bytes
f=n=>{for(i=c=0;c<n;c+=1<g(++i*i+""))g=s=>{for(var l=0;s[l++];)if(!(Math.sqrt(s.slice(0,l))%1)&&!s[l]|(r=!!g(s.slice(l))))return 1+r};return i}

Usage
f(100)
=> 487

Explanation
f=n=>{
  for(
    i=                     // i = current number to check
      c=0;                 // c = number of TanMath numbers found so far
    c<n;                   // keep looping until we have found the required TanMath number
    c+=1<                  // increment the count if it has multiple squares in the digits
      g(++i*i+"")          // check if the current number is a TanMath number
  )
    g=s=>{                 // this function is passed a number as a string and returns the
                           //     number of squares found (max 2) or undefined if 0
      for(var l=0;s[l++];) // loop through each digit
                           // ('var' is necessary because the function is recursive)
        if(
          !(Math.sqrt(     // check if the square root of the digits is a whole number
            s.slice(0,l)   // get the digits to check
          )%1)&&
          !s[l]|           // finish if there are no more digits left to check
          (r=!!            // r = true if number of squares in remaining digits > 0
            g(s.slice(l))  // get number of squares in remaining digits
          )
        )
          return 1+r       // return number of squares found
    };
  return i                 // return the number that the loop finished at
}

Jelly, 14 12 bytes
²ŒṖḌṖÆ²PƇµ#Ṫ

Try it online!
How it works
²ŒṖḌṖÆ²PƇµ#Ṫ - Main link. Takes no arguments
         µ#  - Read n from STDIN and run the following over k = 1, 2, 3, ... until n integers return True:
²            -   Yield k²
 ŒṖ          -   Yield all partitions of k²'s digits
   Ḍ         -   Convert each list of digits back into a number
    Æ²       -   Yield 1 for perfect squares and 0 otherwise
      PƇ     -   Remove all lists with any zeros
                This returns an empty list (falsy) for non-TanMath numbers
                 and a non-empty list (truthy) for TanMath numbers
           Ṫ - Return the last element i.e. the nth number for which the above is true

Raku, 44 bytes
{grep({$^a²~~/^<{(^$a)>>²}>+$/},1..*)[$_]}

Try it online!
The runtime of this inflates fast, due to bruteforcing the combination of powers in the regex. If this were a decision-problem instead, then the submission could just be that central codeblock instead.

Lua, 148 bytes
c=...r=load"a=a or...==''for p=0,...and n-1or-1 do p='^'..p*p..'(.*)'r(p.match(...,p))end"n=-1repeat
n=n+1r(n*n)c,a=c-(a and 1or 0)until c<1print(n)

Lua 5.3 is required
$ lua program.lua 1
7
$ lua program.lua 10
37
$ lua program.lua 100
487

Python 3, 283 243 bytes
This is a brute-force implementation. Golfing suggestions welcome.
from itertools import*
def t(n):
 a=m=0
 while a<n:m+=1;d=str(m*m);r=range(1,len(d));c=[i*i for i in range(m)];a+=any(all(p in c for p in q)for q in[[int(d[x:y])for x,y in zip((0,)+j,j+(None,))]for i in r for j in combinations(r,i)])
 return m

Ungolfed:
import itertools
def tanmath(n):
    a = 0
    m = 0
    while a < n:
        m += 1
        d = str(m*m)
        squares = [i*i for i in range(m)]
        z = []
        # partitions code
        for i in range(1, len(d)):
            for j in itertools.combinations(range(1, len(d)), i):
                partition_indices = zip((0,)+j, j+(None,))
                z.append([int(d[x:y]) for x, y in partition_indices]
        # end partitions code
        if any(all(p in squares for p in q) for q in z):
            a += 1
    return m


text:
Determine the color of a chess square
Your challenge is to write a program that outputs the color of a given square from the chessboard. This is how a chessboard looks:

You can see that the square a1 is dark, and h1 is a light square. Your program needs to output dark or light, when given a square. Some examples:
STDIN:  b1
STDOUT: light

STDIN:  g6
STDOUT: light

STDIN:  d4
STDOUT: dark

The rules:

You need to provide a full program that uses STDIN and uses STDOUT to output dark or light.
Assume that the input is always valid ([a-h][1-8])
This is code-golf, so shortest amount of bytes wins!

Scoreboard

var QUESTION_ID=63772,OVERRIDE_USER=8478;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="
"+e.body.replace(OVERRIDE_REG,"")+"
")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
 <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">

Leaderboard

	Author	Language	Size

Winners by Language

Language	User	Score

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

Why hasn't anyone tried <>^Fish?

shortest amount of bytes total or in a given language?

GS2, 17 15 bytes
de♦dark•light♠5

The source code uses the CP437 encoding. Try it online!
Verification
$ xxd -r -ps <<< 6465046461726b076c696768740635 > chess.gs2
$ wc -c chess.gs2
15 chess.gs2
$ gs2 chess.gs2 <<< b1
light

How it works
d               Add the code points of the input characters.
 e              Compute the sum's parity.
  ♦             Begin a string literal.
   dark
       •        String separator.
        light
             ♠  End the string literal; push as an array of strings.
              5 Select the element that corresponds to the parity.

That's amazing! With 9 unavoidable bytes, 3 byte outgolfing Pyth and CJam is amazing.

Holy cow, guys, GS2 is the new Pyth! Somebody figure it out how to use it well before Denni...never mind.

Did you just steal GS2's powerful string literal system to Jelly?

Python 2, 41 38 bytes
print'ldiagrhkt'[int(input(),35)%2::2]

3 bytes thanks to Mego for string interlacing
Takes input like "g6". That's light and dark intertwined.

That's just gorgeous with the string interlacing.

I'd actually say that int(input(),35) is the brilliant part. I thought of the string interlacing, but your input method saves the most bytes.

+1 if you un-golf and explain your answer, please

Hexagony, 34 32 bytes
,},";h;g;;d/;k;-'2{=%<i;\@;trl;a

Unfolded and with annotated execution paths:

Diagram generated with Timwi's amazing HexagonyColorer.
The purple path is the initial path which reads two characters, computes their difference and takes it modulo 2. The < then acts as a branch, where the dark grey path (result 1) prints dark and light grey path (result 0) prints light.
As for how I compute the difference and modulo, here is a diagram of the memory grid (with values taken for the input a1):

Diagram generated with Timwi's even more amazing Esoteric IDE (which has a visual debugger for Hexagony).
The memory pointer starts on the edge labelled row, where we read the character. } moves to the edge labelled col, where we read the digit. " moves to the edge labelled diff where - computes the difference of the two. ' moves to the unlabelled cell where we put the 2, and {= moves to the cell labelled mod where we compute the modulo with %.
This might be golfable by a few bytes by reusing some of the ;, but I doubt it can be golfed by much, certainly not down to side-length 3.

Ooh, pretty colors!

This language is new to me but I am amazed at your ability to come up with something more contrived than I thought possible

I really don't get all these golf languages.

@codeSwift4Life Hexagony is far from being a golfing language. For trivial tasks like this it might be reasonably competitive, because it has single-character commands, but that is more a necessity shared by many other 2D languages, including Befunge, Piet, ><>. Any nontrivial task will require very large amounts of code and complicated programs, due to Hexagony's weird memory model. It is in no way meant to be a concise language, but rather an exotic and weird one, exploring programming on hexagonal grids.

@qwr I thought being contrived was the point of esolangs. ;)

Wow...I never bothered trying to figure out how the hexagonal memory model worked, but your example (paired with the diagram) just snapped into place in my brain. Wish there were somewhere I could +1 the language!

@ETHproductions Well, there's this meta post and you can star it on GitHub if you want. :P

CJam, 18 bytes
r:-)"lightdark"5/=

Online demo
Dissection
r               e# Read a token of input
:-              e# Fold -, giving the difference between the two codepoints
)               e# Increment, changing the parity so that a1 is odd
"lightdark"5/   e# Split the string to get an array ["light" "dark"]
=               e# Index with wrapping, so even => "light" and odd => "dark"

your code is smiling :-)

I did consider the equally effective :^)

Please can you explain how this works.

@Fogmeister, added explanation.

sed, 37
s/[1357aceg]//g
/^.$/{clight
q}
cdark

Explanation
s/[1357aceg]//g removes all odd-indexed coordinates.  The resulting pattern buffer then has length of 1 for "light" or length of 0 or 2 for "dark".  /^.$/ matches the 1-length patterns, changes the pattern to "light" and quits.  Otherwise the pattern is changed to "dark".

The q is redundant, and you can check for dark first instead with /../, https://tio.run/##K05N@f@/WD/a0NjUPDE5NT1WXz@dS19PTz85JbEomys5JzM9o@T//yRDrnQzrhQTAA

ShadyAsFuck, 91 bytes / BrainFuck, 181 bytes
My first real BrainFuck program, thank Mego for the help and for pointing me to the algorithm archive. (That means I didn't really do it on my own, but copied some existing algorithms. Still an experience=)
NKnmWs3mzhe5aAh=heLLp5uR3WPPPPagPPPPsuYnRsuYgGWRzPPPPlMlk_PPPPPP4LS5uBYR2MkPPPPPPPP_MMMkLG]

This is of course the translation from my brainfuck answers:
,>,[<+>-]++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[-]++++++++++[>++++++++++<-]<[<+>>+<-]<[>+<-]+>>[>++++++++.---.--.+.++++++++++++.<<<->>[-]]<<[>>>.---.+++++++++++++++++.-------.<<<-]

Developed using this interpreter/debugger.
I stole two code snippets for divmod and if/else from here. (Thanks to @Mego!)
,>,               read input
[<+>-]            add
++<               set second cell to 2

Now we have the cells config >sum 2 we now perform the divmod algorithm:
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>
[-]>

The output of the divmod looks like this 0 d-n%d >n%d n/d but we zeroed the d-n%d and are zeroing the next cell too:
>[-]

Fill one cell up to the value 100 for easier outputting:
++++++++++[>++++++++++<-]<

Now the configuration is >cond 0 100 and for applying the if/else algorithm we need two temp variables, so we choose the configuration temp0 >c temp1 100
c[<temp0+>>temp1+<c-]<temp0[>c+<temp0-]+
>>temp1[
 #>++++++++.---.--.+.++++++++++++.<         outputs light
 <<temp0-
>>temp1[-]]
<<temp0[
 #>>>.---.+++++++++++++++++.-------.<<<     outputs dark
temp0-]

Python 2, 45 bytes
print'dlairgkh t'[sum(map(ord,input()))%2::2]

Takes input like "a1". Try it online

This wouldn't work in Python 3 due to the lack of parens for the print.

Can't test right now but something like "ldiagrhgt"[expression::2] should work while saving a byte or two

Seriously, 19 bytes
"dark""light"2,O+%I

Takes input like "a1"
Try it online (you will have to manually enter the input; the permalinks don't like quotes)

Online link ded..

Pyth, 18 bytes
@c2"lightdark"iz35

Interpret the input as a base 35 number, chop lightdark in half, print.

JavaScript (ES6), 45 bytes
alert(parseInt(prompt(),35)%2?"dark":"light")

way to go to use a radix! +1 FTW...

Is there a particular reason alert and prompt have to be the way that STDOUT and STDIN are interpreted for JavaScript? If a normal arrow function is allowed, then it would just be: x=>parseInt(x,35)%2?"dark":"light"

@SteveBennett the challenge asks for a full program so a function wouldn't be allowed as that requires separate code to execute it.

But your code isn't a "full program" either because it would need to be embedded within an HTML page running in a browser.  Seems like kind of a dodgy requirement.

Turing Machine Code, 235 bytes
Using the rule table syntax defined here.
0 a _ r 1
0 c _ r 1
0 e _ r 1
0 g _ r 1
0 * _ r 2
1 2 _ r 3
1 4 _ r 3
1 6 _ r 3
1 8 _ r 3
2 1 _ r 3
2 3 _ r 3
2 5 _ r 3
2 7 _ r 3
* * _ r 4
3 _ l r A
A _ i r B
B _ g r C
C _ h r D
D _ t r halt
4 _ d r E
E _ a r F
F _ r r G
G _ k r halt

This is possibly the most amazing thing I have ever seen lol

TI-BASIC, 66 bytes
Tested on a TI-84+ calculator.
Input Str1
"light
If inString("bdfh",sub(Str1,1,1)) xor fPart(.5expr(sub(Str1,2,1
"dark
Ans

Here's a more interesting variation on the third line, which sadly is exactly the same size:
Input Str1
"dark
If variance(not(seq(inString("bdfh2468",sub(Str1,X,1)),X,1,2
"light
Ans

You'd think TI-BASIC would be decent at this challenge, since it involves modulo 2. It's not; these solutions seem to be the shortest possible.
We spend a lot of bytes to get both characters in the string, but what really costs is the thirteen two-byte lowercase letters.

Befunge-93, 39 37 33 31 bytes
All credit to Linus who suggested this 31-byte solution:
<>:#,_@  v%2-~~
"^"light"_"krad

Test it using this interpreter.
Explanation
<        v%2-~~

The < at the beginning sends the instruction pointer to the left, where it wraps around to the right. It then reads in two characters from input as ASCII, subtracts them, and does a modulo by 2. As a and 1 are both odd (in terms of ASCII code), this works. The v redirects the instruction pointer downward...
"^"light"_"krad

...onto the _, which sends the instruction pointer to the left if the top of stack is 0 and to the right otherwise. The characters of "light" or "dark", respectively, are pushed onto the stack in reverse order. Both paths hit the ^ at the left, which sends the instruction pointer upward...
 >:#,_@

...to the output segment. : duplicates the top of stack, # jumps over the , and onto the _, which sends the instruction pointer to the right if the top of stack is 0 and left otherwise. When the stack is empty, the top of stack (after :) is 0, so the instruction pointer hits the @ which stops execution. Otherwise, it hits the ,, which outputs the top of stack as a character, and then the # jumps it over the : and onto the >, which starts the process again.

save a byte using rad"v>"k without a space?

@Linus: "The space is necessary because otherwise the output would be dar k." Try it in the linked online interpreter.

Your right. Anyway, I was going to do this in befunge but I can only get 2 bytes under you... <>:#,_@  v%2-~~\n"^"light"_"krad, fix the newline.

@Linus: That's brilliant. Thanks!

@JamesHolderness, No hard feelings. You're right to point out this doesn't work in the original Befunge-93 interpreter, the actual spec is for an 80x25 torus. You might want to post your version as it's own answer and explain the difference. I think at least that would be more practical than debating year-old hobby code with me.

Java, 157 127 124 bytes
interface L{static void main(String[]a){System.out.print(new java.util.Scanner(System.in).nextInt(35)%2>0?"dark":"light");}}

You could use an interface like this : interface i{static void main since the everything in an interface is public by default

C, 55 bytes
s;main(){puts(strtol(gets(&s),0,19)&1?"light":"dark");}

Try it online
Thanks DigitalTrauma for lots of golfing tips

I think you have an extra ( after puts

This for 55: s;main(){puts(strtol(gets(&s),0,19)&1?"light":"dark");}.  Assumes that the integer width is big enough to hold 3 chars of string.  You should also be able to do main(s){puts(strtol(gets(&s),0,19)&1?"light":"dark");} for 54, though for some reason gets() is returning garbage is s if not global, so it segfaults.

oh wow, base-19. clever.

Japt, 23 22 bytes
Japt is a shortened version of JavaScript. Interpreter
Un19 %2?"dark":"light"

How it works
          // Implicit: U = input string
Un19      // Convert U from a base 19 number to decimal.
%2        // Take its modulo by 2.
?"dark"   // If this is 1, return "dark".
:"light"  // Else, return "light".
          // Implicit: output last expression

Using the new version 0.1.3 (released Nov 22), this becomes 17 bytes, shorter than all but GS2:
Un19 %2?`»rk:¦ght

Or, alternatively, a magic formula: (26 bytes)
Un19 %2*22189769+437108 sH
Un19 %2                    // Convert input to base 19 and modulo by 2.
       *22189769+437108    // Where the magic happens (top secret)
                        sH // Convert to a base 32 string.

C, 49 bytes
main(c){gets(&c);puts(c+c/256&1?"light":"dark");}

No, that doesn't compile.

Oh, my bad, I had fiddled with something else. The output is wrong, though. I think you meant to do gets(&c)%256+c/256?

Oh, good catch. Though at this point, my solution is strictly worse than yours as we're using the same technique. Looks like I have plenty to learn.

It turns out that the wrong output was caused by the return value of gets(&c). I have updated my submission accordingly.

TeaScript, 23 bytes
®x,35)%2?"dark":"light"

Unfortunately the strings dark and light can't be compressed.

Hehe, Japt is shorter for once ;) +1 though, the JS compression techniques are great! I may add them into Japt after revamping the interpreter.

BotEngine, 165 14x11=154
v acegbdfh
>ISSSSSSSS
 v<<<<>v<
     >   ^
>     >  v
^S2   ^S1el
^S4   ^S3ei
^S6  P^S5eg
^S8 te^S7eh
     ^   <

Here it is with the different path segments highlighted:

(Any non-space characters not highlighted serve as arguments for the e and S instructions- each of these instructions uses the symbol to the left (relative to the bot's direction of travel) as its argument)

Ruby, striked out 44 36 bytes
puts %w[light dark][gets.to_i(19)%2]

You can save a byte by replacing puts  with $><< (no space).

@Mauris I know, but i like my terminating newline

You can save 3 bytes by changing puts for p

, 26 chars / 34 bytes
ô(שǀ(ï,ḣ)%2?`dark`:`light”

Try it here (Firefox only).

I wouldn't call it "compression" if it takes more bytes :P

I'm more worried about chars than bytes at this point. I've entirely given up on trying to golf down byte count in ...

We always score by bytes, and while it's often interesting to optimize for a secondary objective, remember that the fewest bytes always wins.

Yeah, I understand that. I'm not really aiming for winning as much though.

Clojure, 63 bytes
(pr (['light 'dark] (mod (Integer/parseInt (read-line) 35) 2)))

We read in a line from stdin with (read-line)
Then parse the string into an integer value in base 35 using a call to a JVM method
Taking mod of the result 2 tells us if it is even or odd
Use the result returned from the modulo function as an index to the sequence and print it

I save a worthy 2 bytes by quoting out "light" and "dark" with a single quote so that Clojure takes it as a literal, as opposed to wrapping each word in a pair of quotation marks. I also save a few bytes by using pr rather than println.
Some info on quoting in Clojure

Welcome to Programming Puzzles and Code Golf! This is a nice first answer. :) I'm not too familiar with Clojure; would you mind adding an explanation?

Absolutely! There you go. Let me know if you have any questions!

O, 22 17 bytes
i#2%"light'dark"?
This does what it is required to do, with no additional benefits.

C, 46 bytes
main(c){gets(&c);puts(c%37%2?"light":"dark");}

Expects an environment where ints are stored little-endian, and are at least two bytes.
Explanation
c is argc, so initially it contains 01 00 00 00. gets will read two chars, say a (0x61) and 1 (0x31), and store them in c, which is now
61 31 00 00

representing the number 0x3161, or 12641.
Essentially, in this problem, given c = x + 256*y, we want to compute (x + y) mod 2, and print a string accordingly. To do this, I could have written c % 255 % 2, as then
  (x + 256 * y) % 255 % 2
= (x % 255 + y % 255) % 2      since 256 ≡ 1 (mod 255)
= (x + y) % 2                  since 0 < x, y < 255

However, 37 also works:
  (x + 256 * y) % 37 % 2
= (x % 37 - 3 * (y % 37)) % 2  since 256 ≡ -3 (mod 37)

x is in the range 49-57 inclusive (digits 1-8), so x % 37 == x - 37.
y is in the range 97-104 inclusive (lowercase a-h), so y % 37 == y - 74.
This means we can simplify to
= (x - 3 * y + 185) % 2
= (x + y + 1) % 2              since -3 ≡ 185 ≡ 1 (mod 2)

and simply flip the strings to correct for the parity.

Beam, 127 bytes
rSr>`+v
   ^  )
n(`)nS<
    >L'''''>`+++++)S>`+++)@---@'''>`+++++)++@-------@H
>L'''''>`+++)S>`++++++)+++@---@--@+@'''>`++++)@H

An explanation

Light blue - read a character from input into beam, save the beam value into the store, read a character from input into beam.
Dark blue - Adds store to beam by decrementing store to 0 while incrementing the beam
Light green - An even odd testing construct.  The loop will exit to the left if the beam is even or the right if odd.
Dark green - Outputs dark
Tan - Outputs light

Matlab, 51 bytes
I do not think this needs any explanation=)
a={'light','dark'};disp(a(2-mod(sum(input('')),2)))

Minkolang 0.12, 28 24 bytes
on+2%t"dark"t"light"t$O.

Try it here.
Explanation
o                   Take character from input
n                   Take integer from input
+                   Add
2%                  Modulo by 2
t      t       t    Ternary; runs first half if top of stack is 0, second half otherwise
 "dark" "light"     Pushes the string "dark" or "light", depending.
$O.                 Output the whole stack as characters and stop.

Labyrinth, 48 46 45 42 bytes
Thanks to Sp3000 for saving two bytes.
-,"
#
%0:::8.5.3.4.116.@
1
00.97.114.107.@

Try it online!
Explanation
The beginning of the code is a funny dead end. Remember that Labyrinth assumes an infinite number of zeroes when it requires operands at the bottom of the stack. The code starts one the - going right, which tries to subtract two numbers, so the stack becomes:
[ ... 0 ]

Then , reads the first character, a say:
[ ... 0 97 ]

The " is a no-op, but this is also a dead-end so the instruction pointer turns around and starts going to the left. Then ` reads the other character, 2 say:
[ ... 0 97 50 ]

This time, - subtracts those two numbers:
[ ... 0 47 ]

The IP now follows the bend of the "corridor". The # gets the stack depth, ignoring the implicit zeroes, which conveniently happens to be 2:
[ ... 0 47 2 ]

And % computes the modulo:
[ ... 0 1 ]

At this point, the IP is at a junction. If the top of the stack is zero, it will move straight ahead, where 100.97.114.107.@ prints dark. But if the top of the stack is non-zero (specifically, 1), it will move to the right, where 0:::8.5.3.4.116.@ prints light (note that we can omit the leading 1, because there is already a 1 on the stack, and we can save on the repeated 10 in 108, 105, 103, 104 by making a few copies of the 10 when we first get there).

Brian & Chuck, 66 bytes
,>,_{->-?+{-_?>}<?light{-_?>}>>?dark?
II{<?}<<<?{<{<<<?_>.>.>.>.>.

Probably still golfable, but I think I'd need another approach.
Explanation
,>, reads input into Chuck, replacing the two Is. Next is the following part of the code:
   _{->-?
  {<?

which decrements both input elements until the latter (i.e. the digit) reaches zero. This stops Brian's ? from passing control to Chuck, continuing on.
The next + increments the zeroed digit to a 1 so that following uses of { don't get caught on it. At this point, the first cell of Chuck's tape has the difference of the two code points, so now we need to take the code point modulo 2. This is done with the following parts:
          A            B            C
          {-_?>}<?     {-_?>}>>?    ?
     }<<<?{<{<<<?

I've labelled the three parts on Brian's tape to make things easier to explain. The {- in parts A and B decrement the first cell on Chuck's tape, and the following ? checks if it's zero. If it's not, then control is passed, and we execute }<<<?. For part A, this moves us to part B. For part B, this moves us to part C, which immediately passes control and we execute {<{<<<?, sending us back to part A. Thus the effect is that we alternate between parts A and B, in a state machine-like way.
Now whether the first cell was zeroed while we were in part A or part B determines what we print. For A, we have:
             ?>}<?light
_               ?_>.>.>.>.>.

which executes >}< to position us on the last ? in Chuck's tape, and then runs >. five times to print "light".
On the other hand, for part B, we have:
                          ?>}>>?dark?
_                _>.>.>.>.>.

which executes >}>> to position us on the first . in Chuck's tape, and then runs >. four times to print "dark".

Brainfuck, 132 bytes
>,>,[<->-]<[->+<[->-]<[<]>]<++++++++++[->++++++++++<]>>[<++++++++.---.--.+.++++++++++++.>->+<]>-[<<.---.+++++++++++++++++.-------.<]

I tried coming up with my own mod 2 algorithm, which is the [->+<[->-]<[<]>].

Batch, 248 223 207 bytes
Because Batch lacks disjunctional conditionals. -18 bytes thanks to @dohaqatar7, and more due to his idea.
@ECHO OFF
SET S=SET
%S%/P I=
%S%L=%I:~0,1%
%S%I=IF %L%==
%S%N=%I:~-1%
%S%A= %S%L=
%I%a%A%0
%I%b%A%1
%I%c%A%0
%I%d%A%1
%I%e%A%0
%I%f%A%1
%I%g%A%0
%I%h%A%1
%S%/A R=N%%2
IF %R%%L% (ECHO light) ELSE (ECHO dark)

I'm not on a windows machine so I can't test right now but, you should be able to save some bytes by abusing variable expansion. Put set a=" set L=" at the top then replace every occurrence of  set L= with %a%.

@dohaqatar7 Oh right you can do that. Thanks!

when SET is used with switches (/A or P) spaces are ignored, like %S%/P I= can be shortened into %S%/PI=. Furthermore, parenthesis around ECHO dark isn't required

Batch, 147 127 126 bytes
@set/pi=
@set/aj=%i:~1%%%2
@goto %i:~,1%
:a
:c
:e
:g
@set/aj=1-j
:b
:d
:f
:h
@if %j%==0 (echo dark)else echo light

Uses goto as a form of switch to increment the row number on alternate columns.
Edit: Saved 15 bytes by reducing the column modulo two up front and then using 1-j to flip between dark and light on alternate columns. Saved 2 bytes by removing some unnecessary ()s. Saved 3 4 bytes by removing some unnecessary spaces.

Bash, 40 bytes
read x;y=(light dark);echo ${y[19#$x%2]}

Not using any coreutils.

Bash + coreutils, 34 36
Using the same base conversion technique as other answers, but I chose base 19.  I think it should work for any odd base between 19 and 35.
x=(light dark)
echo ${x[19#`cat`%2]}

Looks like your code reverses the colors. 1 character shorter: x=(light dark);echo ${x[19#\cat`%2]}`

@manatwork Thanks.  When I tried the array indexing trick before it turned out longer - not sure what I got wrong.  Thanks!

CMD.EXE, 15 + 15 + 10 + 63 = 103 bytes
a1.cmd:
echo dark
exit

a2.cmd:
echo light
exit

Then create hard links for all the remaining 62 squares. Invoke using cmd /k echo off.

It's customary to count each additional file as one byte. That should apply to hard links too.

I think the consensus is that each additional file after the 1st costs you an extra point.  I would argue that hard links count as files for this purpose.

@Dennis you beat me to it by 35 seconds.  Business as usual ;-)

Gol><>, 22 bytes
ii+2%Q"thgil"H|"krad"H

Explanation
ii             Read two chars
+2%            Add code points mod 2
Q        |     If top of stack is truthy...
 "thgil"H        Push "light" and halt, outputting stack
"krad"H        Push "dark" and halt, outputting stack

Haskell, 61 56 Bytes
-5 bytes thanks to Mauris

As always, Haskell's interact function comes through with some byte saving on a challenge with IO.
The program assumes that a STDIN consists of only the row and the column, anything else can throw off the results; although, a trailing newline will not effect the outcome.
main=interact$(cycle["dark","light"]!!).sum.map fromEnum

main=interact$(cycle["dark","light"]!!).sum.map fromEnum for 56 bytes.

Python 2 - 75 bytes
import sys
l,n=sys.stdin.read()
print 'light'if ord(l)&1^int(n)&1 else'dark'

Go, 100 bytes
package main;import."os";func main(){t:=Args[1];k,d:=t[0]+t[1],"light";if k%2==0{d="dark"};print(d)}

Ungolfed:
package main

import . "os" // Import os defines into current namespace

func main() {
    t := Args[1] // Grab the first argument
    // Define k as the sum of the 2
    // first characters of the first argument, then define d as "light"
    k, d := t[0]+t[1], "light"
    // The sum aligns up nicely with the color of the square
    if k%2 == 0 {
        d = "dark"
    }
    print(d)
}

You can save a byte using !k%2 (unless I'm mistaken about precedence)

@cat Go does not support boolean operators on ints

Uhh... oh. I forgot about that. Go gets a little lamer every time I come back to it.

PowerShell, 52 46 45 bytes
("dark","light")[(+($a="$input")[0]+$a[1])%2]

Pretty ugly due to how we have to parse the STDIN input (which, in PowerShell, is weird). The special variable $input is present only if items get piped in, we encapsulate that into a string, and save it into $a. Then, we use the same math trick as other answers to calculate out whether the input is even or odd, and use that to index into our "dark" or "light" output array.
Edit -- saved 6 bytes by using + to cast $a[0] instead of [int]. Saved an additional byte by changing where $a is created by using a code block.

You can drop 3 bytes by replacing [int] with 1*

@Rynant Or, use + and drop the parens to save 6. ;-)

Even better; nice!

Common Lisp, 90 bytes
Not a winner, but makes nice use of ability to read in base 18 and then do arithmetic with that number.
(let((*read-base* 18))(if(evenp(multiple-value-call'logxor(floor(read)18)))"light""dark"))

Marbelous, 86 bytes
..00
..]]//
&0/\]]//
..&0//
..//
^0
=0&1
&2\/
\/
'l'i'g'h't'd'a'r'k
&1&1&1&1&1&2&2&2&2

]]// loops wait for two bytes of input, then add them together and use ^0 and =0 to check the LSB and drop "light" or "dark" to stdout.

Perl, 29 27 bytes
$_=/./&($'+ord)?light:dark

This code requires the -p switch, which I have counted as 1 byte.
Try it online on Ideone.
How it works

Because of the -p switch, Perl reads one line of input and stores it in $_.
/./ is a regular expression that matches one character. This has two implications:

Since the match is successful, /./ returns 1.
The post-match (second input character) is stored in $'.

$'+ord adds the integer the second input character represents to the code point (ord) of the first character of the implicit variable $_.
& takes the bitwise AND of the return value of /./ and the sum $'+ord, returning 1 is the sum if odd, 0 if it is even.
?light:dark returns light if the previous expression returned 1 and dark otherwise.
Finally $_= assigns the result to $_, which Perl prints automatically, because of the -p  switch.

Vitsy, 23 22 21 Bytes
Thanks to @El'endiaStarman for shaving off a byte!
New Method (using fancy stack mechanics):
"krad"&"thgil"z+2M(?Z
Explanation:
"krad"&"thgil"z+2M(?Z
"krad"                 Push "dark" (backwards) to the stack.
      &                Generate a new stack.
       "thgil"         Push "light" (backwards) to the stack.
              z        Grab all input as string.
               +       Add up the input's ASCII values.
                2M     Modulate by 2.
                  (    If the result is not zero, do the next item.
                   ?   Rotate over a stack.
                    Z  Output everything in the current stack.
Original Method (using fancy line-specific execution mechanics):
z+2M1+mZ
"krad"
"thgil"
How it works:
z+2M1+mZ
z        Grab all input as string.
 +       Add it together.
  2M     Modulo by 2.
    1+   Add 1
      m  Go to the line specified by the top item of the stack - if it's one,
         it'll push "light" to the stack. If 2, "dark".
       Z Output everything in the stack.

C# (Visual C# Interactive Compiler) - 122 42
Write((Read()+Read())%2<1?"dark":"light");

Reads from STDIN
Format is simply a1

Thanks to @dana for the change from C# to the current one & golfing a ton of bytes! :)
Try It Online!

I got it down to 100, but if you switched to the "Visual C# Interactive" REPL you could do better - https://tio.run/##Sy7WTc4vSv3/v7Q4My9dwdk2uLK4JDVXzzk/rzg/J9U6OSexuFghoLq4JLEkM1mhLD8zRcE3MTNPQ7PaWS@8KLMkVUPDWS8oNTFFQ1MbxtBUNbIxtFdKSSzKVrJSyslMzyhR0rSurf3/P8kIAA

42 bytes - https://tio.run/##Sy7WTS7O/P8/vCizJFVDIyg1MUVDUxtCaaoa2RjaK6UkFmUrWSnlZKZnlChpWv//n2QEAA

JavaScript ES6, 59 56
s=prompt()
alert((s.charCodeAt()^s[1])%2?"light":"dark")

Extracts the number and the ASCII code of the letter, adds them and checks if even/odd. This can accept input in the form a1 and A1
3 bytes saved thanks to Neil!

Requires input from STDIN, not a function.

I didn't see that part. Edited

You can save a couple of bytes by using ^ instead of - - and the 0 is unnecessary.

Bash, 69 Bytes
sed 's/^./(&+/;s/$/)%2/'|tr [a-h] [1-8]|bc|sed s/1/light/\;s/0/dark/

Probably could be optimized a bit more.

The first sed formats the input to be from the form a5 to (a+5)%2
tr takes the letters a-h and converts them to 1-8 respectively
bc performs the addition and modulo
the final sed then takes the result and formats it as a string.

MATL, 20 bytes
js2\?'light'}'dark']

Explanation
j              % input string
s              % sum
2              % push 2
\              % mod(sum(inputstring),2)
?              % if this value is 1
  'light'      % return 'light'
}              % else
  'dark'       % return 'dark'
]              % end

Was MATL written before this challenge?

Oh, I forgot about that. The first version was published in october as far as I know, but I am not sure whether this is valid code in the first version.

Yes, the language was in draft in October with a preliminary version of the interpreter also available.  The esolangs.org page was also created at that time... so I think you're good here flawr.

Vert nice use of mod!

Well I basically just translated my matlab answer=)

Julia 1.0, 43 bytes
print([:dark,:light][sum(read(stdin))%2+1])

Try it online!

Shue, 80 bytes
light
dark
bb=
b=light
=dark
a=
c=
d=b
e=
f=b
g=
h=b
1=
2=b
3=
4=b
5=
6=b
7=
8=b

Try it online!
Pretty sure this is optimal. The empty string represents even letters/integers and a "b" represents odd letters/integers.

Factor + math.unicode, 36 35 bytes
readln Σ odd? "light""dark"? print

Try it online!

K (ngn/k), 25 bytes
{$[2!+/x;"light";"dark"]}

Try it online!
Simple if statement.
Explanation:
{$[2!+/x;"light";"dark"]}    Main function. Takes x as input
 $[                    ]     If
     +/x                     Sum of ASCII charcodes of x
    !                        Modulo by
   2                         2
        ;                    If the result is 1 (i.e. an odd number)
         "light"             Return string "light"
                ;"dark"      Else, return string "dark"

hint: use indexing, symbols, and a train shorten it by ≈⅓

Microscript, 25 bytes
Because Microscript II really doesn't have much in terms of character manipulation yet.
2sI++%{"thgil"ah}"krad"ah

PHP, 40 42 bytes
PHP is doing OK this time:
<?=intval(fgets(STDIN),35)%2?dark:light;

Edits

Saved 2 bytes by using <?= instead of echo. Thanks to Martijn.

40 chars: <?=intval(fgets(STDIN),35)%2?dark:light;

@Martijn Sometimes you can't see the simplest things. Thanks a lot.

ShapeScript, 57 56 bytes
0'1+@"%c"2?862**+%$"%d"2?%~@'8*!#!+"dark"@"light"@'@'*!#

Try it online!
How it works
0         Push 0 (accumulator).
'         Push a string that, when evaluated, does the following:
  1+        Increment the accumulator.
  @         Swap it with the input.
  "%c"      Push that formatting string.
  2?        Copy the accumulator.
  862**+    Add 8 * 6 * 2 = 96 to it.
  %         Apply the string formatting: 1 ... 8 -> 'a' ... 'h'
  $         Split the input at occurrences of that character.
  "%d"      Push that formatting string.
  2?        Copy the accumulator.
  %         Apply the string formatting: 1 ... 8 -> '1' ... '8'
  ~         Join the split input, using that character as separator.
  @         Swap the result with the accumulator.
'
8*        Repeat the string eight times.
!         Evaluate.
#         Discard the accumulator.
!         Evaluate the modified input. Pushes two integers.
+         Add the integers.
"dark"@   Swap the sum with that string.
"light"@  Ditto.
'@'*!     Repeat the at sign (swap) that many times and evaluate the result.
          An odd number of swaps brings "dark" on the top of the stack.
#         Discard the topmost string.

Mouse, 25 bytes
?'?'+2\["light"$]"dark"$

Explanation:
?'?'                       ~ Read two characters from STDIN and put their ASCII
                           ~ codes on the stack
    +2\                    ~ Get the sum of the codes modulo 2
       ["light"$]          ~ If the result is 1, print light to STDOUT and exit
                 "dark"$   ~ Print dark to STDOUT and exit

SpecBAS - 59 bytes
My original version (before looking at any other answers) was 117 bytes and probably reflects the way I come at a problem. Then I saw everyone using base 19 or 35, which wouldn't have sprung to my mind at all.
So, with thanks to everyone else for getting this down to 59.
1 INPUT s$: PRINT IIF$(DECIMAL(s$,19) MOD 2,"Dark","Light")

Prints "Dark" if converted number mod 2 is 1/True and "Light" otherwise, using the inline if statement.

Burlesque, 25 bytes
)**++"dark light"wdcyj!!Q

One-to-one translation from the 56 bytes Haskell solution to this challenge:
)**++             -- sum . map fromEnum
"dark light"wdcy  -- cycle["dark","light"]
j                 -- swap
!!                -- same as Haskell !!

R, 163 bytes
Thanks to Alex A. for helping me with this answer.
n<-toupper(unlist(strsplit(scan(,""),"")));cat(matrix(rep(c(rep(c("light","dark"),4),rep(c("dark","light"),4)),4),8,8,dimname=(list(8:1,LETTERS[1:8])))[n[2],n[1]])

Example usage
1: b1
2:
Read 1 item
light

1: d4
2:
Read 1 item
dark

There's surely a better way to do this. I just made a matrix filled with the string "light" or "dark" to match the chessboard and then used subscripts taken from the input to return the color of the square.

Alright, I took your suggestions and fixed it. Thanks for your help!

Here's some tips for golfing in R.  Couple of things that stand out.  Replace <- with =.  toupper isn't required, but you'll need to use letters rather than LETTERS.   You could create a 9 x 9 matrix using matrix(c('dark','light'),9,9).  It will throw a warning, but I don't think that's a problem.  You could also play around with charToRaw.  So keeping the same sort of logic you could reduce it to something like cat(matrix(c('dark','light'),9,9)[(n=as.integer(charToRaw(scan(,'')))-c(96,48))[1],n[2]])

><>, 31 bytes
ii+2%?\"krad"oooo;
l"oc0.\"thgi

Here I'm thinking "there's got to be a better way..."

R, 65 bytes
cat(c("dark","light")[1+sum(strtoi(charToRaw(scan(,"")),16))%%2])

Ungolfed:
# Get the ASCII codes from the input string
a <- strtoi(charToRaw(scan(, "")), 16L)

# Compute the sum modulo 2
s <- sum(a) %% 2

# Use the sum as an index for the output
cat(c("dark", "light")[s + 1])

54 bytes

Scala, 65 53 49 bytes
It's quite clear without ungolfing.
print(Seq("dark","light")(readLine.sum.toInt%2))

GolfScript, 21 bytes
{^}*~1&"lightdark"5/=

Explanation:
{^}*            # XOR the bytes of the input together
~               # negate the result
1&              # extract only the lowest bit (i.e. 0 or 1)
"lightdark"5/   # split the string "lightdark" into the array ["light" "dark"]
=               # use the bit as an index into the array, returning "light"
                # for 0 and "dark" for 1

Conveniently, since the ASCII codes of a Unix-style newline (LF = ASCII 10) and a space (ASCII 32) are even, this code can handle arbitrary spaces and linefeeds in its input.  Both upper- and lowercase letters are also accepted, and the letter can be given before or after the number.  Tabs or carriage returns, however, will throw it off.
Not unexpectedly, this program is quite similar to Peter Taylor's CJam entry.  I didn't actually look at any of the other entries before I wrote this, though.

Prolog, 80 bytes
p:-read(X),string_codes(X,[A,B]),Y is(A+B)mod 2,(Y=0->write(dark);write(light)).

Try it online here

/\1 instead of mod 2 + removing the parens around (A+B) saves a few bytes

PlatyPar, 21 bytes
X,u#^2%?"dark"\"light

Explanation
X,u#^                  ## charcode of the letter XOR the number
     2%?      \        ## if it is odd
        "dark"         ## output "dark"
               "light  ## else output "light

Try it online!

Lua, 53 Bytes
l,n=(...):byte(1,2)print(l%2==n%2 and"dark"or"light")

Pretty simple, takes command line input through ... and assigns variables l and n to the first and second byte of the input and then checks the ASCII value of each. If both are even or both are odd, the square is dark, else the square is light.

><> Fish 26 bytes
d"darkthgil"ii+2%?!rooooo;

A spin on the already posted fish code by sp3000.
It uses the same based checking with mod but with a few changes.
Using 1 line allows us to save 6 bytes (1 for the new line, 2 for directional instructions and 3 for the jump instructions)
Lose 1 byte to placing a [CR] onto the stack but it allows us to use 5 prints on both answers.
Lose 1 byte to reversing the stack [r] when needed for an answer.
Lastly putting both answers on the stack in 1 string allows us to save 2 bytes not having to use ["] twice.

SmileBASIC, 66 bytes
INPUT L$N=INSTR(@bdfh,L$)<0!=VAL(POP(L$))MOD 2?"light"*N;"dark"*!N

explanation:
INSTR(@bdfh,L$)<0 'Checks if L$ is b,d,f,h. @bdfh is a label, equivalent to the string "@bdfh"
!= 'used as a logical XOR, which SB doesn't have.
VAL(POP(L$))MOD 2 'Checks if the row is odd. Also removes the second character of L$,
                   'which makes the first check shorter since SB evaluates right to left.
?"light"*N;"dark"*!N 'this turned out to be shorter than using IF/THEN/ELSE.

K (oK), 16 bytes
`dark`light 2!+/

Try it online!
+/ sum the (code points of the) argument
2! mod-2
`dark`light  select that from this list of symbols

Jelly, 11 bytes
OḂEị“_ß“ṗɠ»

Try it online!

Why not just OSị“ṗɠ“_ß» for 10 bytes?

Vyxal, 11 bytes
C∑₂`⟇ǎ↔β`½i

Try it Online!
Explanation:
C∑₂`⟇ǎ↔β`½i ; takes the coordinate
C           ; character values of the input
 ∑          ; sum of char values
  ₂         ; is even?
   `⟇ǎ↔β`   ; compressed string "lightdark"
         ½  ; split in half (yielding ["light", "dark"])
          i ; index into

Fig, \$11\log_{256}(96)\approx\$ 9.054 bytes
iHD,[jn("OS

Try it online!
iHD,[jn("OS
          S # Sum charcodes
         O  # Is odd?
i           # Use that as the index for...
  D,[jn("   # The compressed string "darklight"
 H          # Halved, yielding ["dark", "light"]

Nibbles, 15 14 13 bytes
=+.@o$%`D-21~8fd905cff4e

Attempt This Online!
Explanation
   @                      - input
  . o$                    - as codepoints
 +                        - sum
=     %`D-21~8fd905cff4e  - index in compressed list ["light", "dark"] (wrapped)

-2 bytes thanks to Dominic van Essen

Nice!  You can also save one byte (2 nibbles) using data to encode the "light" "dark" array: =%+.@o$2%`D-21~8fd905cff4e...

Also, Nibbles indexing wraps around by default, so you can leave-out the %2 altogether to save another byte: =+.@o$%`D-21~8fd905cff4e

Haskell + hgl, 31 bytes
main=io$(Wr"dark light"!)<mF Or

Attempt This Online!
Explanation
All in all we sum the code points and select the correct color based on its value mod 2.

Or converts a character to its codepoint
mF Or folds along a string to sum up the codepoints
Wr splits the string "dark light" along spaces.
! indexes the string wrapping around if the index is greater than 1.
io converts a function into a complete program
main= sets the main and is required by Haskell for complete programs

Reflection
hgl is not good for complete programs. It has the 5 byte penalty forced by a main declaration, and requires some type glue, in this case io, to work. 8 bytes here are devoted to making this a complete program.
This challenge also has stringent io which contributes a lot to the size of the program.
With that in mind the actual logic here is 5-6 bytes which is alright.
Some reflections:

hgl has no string compression. Obviously, since it can't have dedicated syntax, it wouldn't be as effective as other golfing languages, and it would also be a large undertaking to implement it.  But it potentially could have saved in this challenge.
There's an argument to be had that Wr should be 1 byte. If you want to make lists of strings, Wr"..." is usually the way to go.
(!) does not seem to have a prefix variant. It wouldn't help here, even if it were 1 byte, but it should probably exist with a 2-byte name.

AHK, 78 bytes
a=%1%
If Mod(Asc(a)+Asc(SubStr(a,2)),2)=1
s=light
Else
s=dark
FileAppend,%s%,*

AHK uses 1 as the name for the first parameter so you have to assign to a different name before you use it in functions. Otherwise, it'll think you mean the value 1 and not the variable named 1. Also, the only way to report to STDOUT is by using FileAppend with * as the file name.

Chip, 57 bytes
*gS!~s
fA.Z\ZZZvt
cZ}x< eab
>--^/vZZvZZvt
ZZZd ddac ce
ab

Try it online!
XOR's the low bit of each input (like most if not all other answers) to make the decision. Outputs dabh`, bitwise-OR'd with hhe`t for light or ``pc for dark. (Dark also exits one byte early).

Japt, 16 bytes
`ä•Krk`qe g~Uxc

Try it online!
How it works
`ä•Krk`qe g~Uxc

`ä•Krk`          Compressed literal for "lightedark"
        qe        Split with "e"
           g      Take the element at the index (wrapping)...
             U      Input array of chars
              xc    Sum the chars' charcodes
            ~       Take bitwise not, in order to swap parity

The string array compression trick did quite a job here.

15 bytes

05AB1E (legacy), 13 bytes
“–°‡Ž“#I35öÈè

Try it online!
Here is a golf with your own language :)
Explanation
“–°‡Ž“       : compressed: "dark light"
      #      : split by space
            è: select the 0th or 1st element based on {
       I35ö  :  take the input and convert it to int from base 35
           È :  1 if even else 0
               }

APL (Dyalog Unicode), 25 24 bytesSBCS
-1 thanks to Bubbler.
⊃'dark' 'light'⌽⍨+/⎕UCS⍞

Try it online!
⍞ get text from stdin
⎕UCS convert to Universal Character Set code points
+/ sum
'dark' 'light'⌽⍨ use that to cyclically rotate the list of strings
⊃ pick the first

24 bytes.

@Bubbler 23.

OP requires a full program, so the 23 is invalid.

@Bubbler Oh. Hm.

Runic Enchantments, 25 bytes
iu+2%1(8*?"light"@"dark"@

Try it online!
How it works
>                      implicit entry
 i                     read string from input
  u                    break the string into characters
   +                   add them together
    2%                 modulo 2
      1(               compare with 1
        8*             multiply the result (true -> 8, false -> 0)
          ?            pop x, if x is truthy, skip x characters
           "light"@    output light if false
           "dark"@     ouput dark if true

Keg, 12 bytes
+2%[‘15‘|‘1⑻

Try it online!
A Keg port of Dennis' answer.

This is the obvious approach to a trivial question, so I wouldn't consider this a port (or am I missing something?)

I saw Dennis' answer and copied it. It uses the same algorithm as his answer, as in the explanation would pretty much be the same.

Python 3, 40 bytes
print('ldiagrhkt'[int(input(),35)%2::2])

05AB1E, 11 bytes
Port of Dennis's GS2 answer.
“–°‡Ž“#IÇOè

Try it online!
Explanation
“–°‡Ž“      Compressed string "dark light"
      #     Split on spaces
       I    Take an input
        Ç   Codepoints
         O  Sum
          è Modular index into the original list

Stax, 11 bytes
ÄºÉ╨φr°mißâ

Run and debug it
Explanation
|+            Sum the codepoints of the input string
  `ASbEx!"`   Compressed string "dark light"
           j  Split on spaces. ["dark","light"]
            @ Fetch at the corresponding index (modular)

x86-16 machine code, IBM PC DOS, 36 35 bytes
00000000: b408 cd21 8ad0 cd21 32c2 ba1e 01d0 e873  ...!...!2......s
00000010: 02b2 18b4 09cd 21c3 6c69 6768 7424 6461  ......!.light$da
00000020: 726b 24                                  rk$

Listing:
B4 08       MOV  AH, 8              ; DOS read char from STDIN
CD 21       INT  21H                ; first char in AL
8A D0       MOV  DL, AL             ; move to DL
CD 21       INT  21H                ; second char in AL
32 C2       XOR  AL, DL             ; XOR ASCII values to get low bit
BA 011F     MOV  DX, OFFSET D       ; default to "dark" string
D0 E8       SHR  AL, 1              ; put low bit into CF
73 03       JNC  TO_STDOUT          ; if 1, output "dark"
B2 18       MOV  DL, LOW OFFSET L   ; otherwise, "light"
        TO_STDOUT:
B4 09       MOV  AH, 9              ; DOS write string to STDOUT
CD 21       INT  21H                ; DX written to STDOUT
C3          RET                     ; return to DOS

        L   DB   'light$'
        D   DB   'dark$'

Just does a simple XOR on the ASCII values of the two chars and the lowest order bit determines which string to output.
Standalone executable DOS program (since STDIN/STDOUT is a requirement).

-1 byte thx to @l4m2!

BA 0119     MOV  DX, OFFSET L   => MOV DL, L as they're in same 256B

Acc!!, 138 bytes
N+N
Count i while _%2 {
Write 108
Write 105
Write 103
Write 104
Write 116
0
}
Count i while _ {
Write 100
Write 97
Write 114
Write 107
0
}

Try it online!
Pseudocode
Read two characters, add their codepoints, and store the result in the accumulator
While the accumulator value is odd:
    Write l, i, g, h, t
    Set the accumulator to 0
While the accumulator value is nonzero:
    Write d, a, r, k
    Set the accumulator to 0

Rattle, 32 bytes
dark&light&\|!I<gI0nr`gI1R1+\%b`

Try it Online!
Explanation
This essentially just takes the sum of the number and the ASCII value of the letter, sees if it's even or odd, and outputs "dark" or "light" accordingly.

Raku, 42 bytes
say «dark light»[slurp.comb».ord.sum%2]

Try it online!

Thunno B, \$17 \log_{256}(96) \approx\$ 14 bytes
S"ldiagrhkt"ZlsAH

Attempt This Online!
S"ldiagrhkt"ZlsAH   # Implicit input. The B flag gets the ordinals of each character in the input.
S                   # Sum the ordinals
 "ldiagrhkt"        # String "ldiagrhkt"
            Zl      # Uninterleaved to get ['light', 'dark']
              sAH   # Index into this list (1-based, modular)
                    # Implicit output

Go, 97 bytes
package main
import."os"
func main(){o:="light"
if(Args[1][0]+Args[1][1])%2<1{o="dark"}
print(o)}

Attempt This Online!
-3 byte improvement over @Kristoffer Sall-Storgaard's answer.

jq -Rr, 31 bytes
["dark","light"][explode|add%2]

Try it online!

Thunno 2 B, 9 bytes
S‘ɲ⁺/^‘½İ

Attempt This Online!
Explanation
S‘ɲ⁺/^‘½İ  # Implicit input, converted to ordinals by B flag
S          # Sum the list of ordinals of the input
 ‘ɲ⁺/^‘    # Push dictionary compressed string "lightdark"
       ½   # Halve it to get ["light", "dark"]
        İ  # 1-based modularly index the sum into this list
           # Implicit output

Java, 178 bytes
interface z{static void main(String[]a){int b=a[0].charAt(0)-'a',c=a[0].charAt(1)-'0';if(b%2==0&&c%2!=0||b%2!=0&&c%2==0)System.out.print("dark");else System.out.print("light");}}

Takes input as first argument.
Ungolfed:
interface z {
    static void main(String[]a) {
        int b = a[0].charAt(0) - 'a',                               // Convert value from a to value from 0...7
                c = a[0].charAt(1) - '0';                           // Get number
        if (b % 2 == 0 && c % 2 != 0 ||                             // If b is divisible by 2 and c is divisible by 2 or
                b % 2 != 0 && c % 2 == 0)                           // b is not divisible and c is divisible
            System.out.print("dark");                               // output dark
        else System.out.print("light");                             // else output light
    }
}

Tcl, 63 bytes
scan [gets stdin] %c%d h v
puts [expr ($h+$v)%2?"light":"dark"]

Try it online!

QBIC, 38 bytes
~(asc(;)+!_sA,-1|!)%2|?@Light`\?@Dark

Explanation
~(                       IF
  asc( )                 the ascii value of
      ;                  the input string (of the input "b1" only the first char is evaluated by asc())
        + _s ,  |        plus a substring of
            A            A$ (the input, this was assigned to A$ by ;)
              -1         taking only the first char from the right
         !        !      and cast this to num
                   )%2   MODULO 2 (is non-zero, implicit)
|?@Light`                THEN PRINT the literal "Light"
\?@Dark                  ELSE PRINT "Dark" (no terminating ` is needed at EOF)

F# (Mono), 63 bytes
printf(if(stdin.Read()+stdin.Read())%2<1 then"dark"else"light")

Try it online!

Kotlin, 45 bytes
{if(it.sumBy{it-'@'}%2>0)"light" else "dark"}

Try it online!

J, 48 40 37 bytes
>@{&('dark';'light')@{:@#:@+/@(a.&i.)

− 8 bytes by replacing (-2&*@<.@%&2) with {:@#:
− 3 bytes by removing @>:
Try it online!

You can save 8 bytes by taking the sum of the unicode codepoints and taking the result mod 2, instead: ('dark';'light')>@{~2|1#.3&u: Try it online!

...and 1 more byte by changing the constant to ;:@'dark light'

Ly, 29 bytes
ir2%+2%[p"light"&o;]p"dark"&o

Try it online!
This just does module math on the column number to pick a light/dark squares.  The even/odd-ness of the row shifts the calculations.
ir                            - read 2 digit code in as codepoints, reverse stack
  2%                          - even or odd row?
    +                         - add as offset to column
     2%                       - even or odd?
       [p          ]p         - code block run if odd
         "light"&o;           - print "light" and exit
                     "dark"&o - print "dark"

Scala 3, 109 bytes
Golfed version. Attempt this online!
val Q=Integer.parseInt(scala.io.StdIn.readLine,35)%2
println("ldiagrhkt".grouped(2).map(_.apply(Q)).mkString)

Ungolfed version. Attempt this online!
import java.lang.Integer
import scala.io.StdIn

object Main {
  def main(args: Array[String]): Unit = {
    val input = StdIn.readLine()
    val index = Integer.parseInt(input, 35) % 2
    val s = "ldiagrhkt"
    println(s.zipWithIndex.collect{ case (c, i) if i % 2 == index => c }.mkString)
  }
}

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes