title: Fully Modular C: Grading

text:
# Question
Title: Fully Modular C: Grading
You are a Computer Science professor teaching the C programming language. One principle you seek to impart to the students is *modularity*. Unfortunately, past classes have tended not to get the message, submitting assignments with the entire program inside `main()`. Therefore, for this semester you have issued strict modularity guidelines upon which students will be graded.

A subset of C grammar and rules for "well-formed" translation unit are defined below. Code that follows these rules should be valid C89, UNLESS an identifier that is a keyword is used.

### Task

You will receive as input a string purportedly containing C code. You may assume that this string contains only spaces, newlines, and the characters `abcdefghijklmnopqrstuvwxyz123456789(){},+-*/%;=`.

Your code must output the number of points the student's assignment should receive according to the following rubric:

* Input is not a valid `translation-unit` according to the grammar: 0 points
* Input follows the grammar but is not "well-formed" according to the rules below: 1 point
* Input is a well-formed translation unit but not fully modular: 2 points
* Input is a fully modular well-formed translation unit: 3 points

### Token definitions

* `identifier`: Any sequence of 1 or more lowercase English letters. If an identifier is a C89 reserved word1, you may optionally return 0 instead of whatever the result would have been ignoring reserved words. You do not have to be consistent about detecting the use of reserved words as identifiers; you may flag them in some instances and let them pass in others.
* `integer-literal`: A sequence of 1 or more of the digits 1-9 (recall that the character `0` is guaranteed not to appear in the input)
* Other valid tokens are defined literally in the grammar.
* A character must belong to a token if and only if it is not whitespace.
* Two consecutive alphanumeric characters must be part of the same token.

### EBNF grammar

```
var-expr = identifier
literal-expr = integer-literal
binary-op = "+" | "-" | "*" | "/" | "%"
binary-expr = expr binary-op expr
paren-expr = "(" expr ")"
call-expr = identifier "(" [ expr ( "," expr )* ] ")"
expr = var-expr | literal-expr | binary-expr | paren-expr | call-expr
assign-stmt = var-expr "=" expr ";"
if-stmt = "if" "(" expr ")" assign-stmt
return-stmt = "return" expr ";"
function-body = ( assign-stmt | if-stmt )* return-stmt
argument-list = [ identifier ( "," identifier )* ]
function-definition = identifier "(" argument-list ")" "{" function-body "}"
translation-unit = function-definition*

```

### Well-formed program requirements

* No two function definitions may have the same function name.
* No two identifiers in an `argument-list` may be identical.
* No identifier in an `argument-list` may be identical to a function name (whether from a `function-definition` or a `call-expr`).
* The identifier in a `var-expr` must be included in the enclosing function's `argument-list`.
* For a given function, all `call-expr`s and the `function-definition` (if any) must agree in number of arguments.

### Fully modular

* No more than 1 binary operator per function
* No more than 1 assignment statement per function
* No more than 1 function call per function

### Examples (one per line)

**Score 0**

```
}}}}}
return 2;
f() { return -1; }
f() {}
f(x,) { return 1; }
f(x) { return 1 }
f(x) { returnx; }
f(x) { return1; }
f() { g(); return 1;}
f() { if(1) return 5; }
f(x) { if(1) if(1) x = 2; return x; }
f(x, y) { x = y = 2; return x; }

```

**Score 1**

```
f(){ return 1; } f(){ return 1; }
g(x, x) { return 1; }
g(f) { return 1; } f() { return 1; }
f(x) { x = write(); x = write(1); return 1; }
f() { return f(f); }
f() { return 1; } g() { return f(234567); }
f() { return(x); }
f() { j = 7; return 5; }

```

**Score 2**

```
f(x,y,zzzzz) { return x + y + zzzzz; }
f(x,a,b) { if(a) x = foo(); if(b) x = bar(); return x; }
f(j) { return g(h( i() / j, i() ), 1) ; }

```

**Score 3**

```
mod(x, y) { return ((x % y)); }
f() { return f(); }
f(c) { if(c) c = g(c) + 2; return c; }
fib(i){return bb(i,0,1);}aa(i,a,b){return bb(i,b,a+b);}bb(i,a,b){if(i)a=aa(i-1,a,b);return a;}

```

**Score 0 or 1**

```
h(auto, auto) { return 1; }

```

**Score 0 or 3**

```
if() { return 1; }

```

---

1  Reserved word list: `auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while`

# Answer
# JavaScript (ES6), ~~599~~ ~~598~~ ~~593~~ ~~581~~ ~~580~~ ~~576~~ ~~574~~ ~~593~~ ~~591~~ ~~579~~ ~~565~~ ~~563~~ ~~562~~ ~~524~~ ~~521~~ ~~515~~ ~~513~~ ~~511~~ ~~506~~ ~~503~~ 502 bytes

*After over 3 years I finally noticed "some" further golfs. I also found an edge case while re-golfing… +19 bytes. ~~Sigh.~~ That helped me notice a 38 byte golf. :P*

```
M=p=>(P=I[i++])==p&&7
J=_=>/^[a-z]+$/.test(R=P)*7
O=(Z,a,n=R)=>M`)`?(L[n]|=2)&1|U[n]-(U[n]=a)?1:7:(a++?P==",":i--)&&Z()&O(Z,a,n)
E=_=>(M`(`?E()&M`)`:P-~P?7:J()&(M`(`?O(E,!++z):A[i--,R]|1))&(/[+*/%-]/.test(I[i])?E(++y+i++):7)
S=_=>M`return`?E()&M`;`&M`}`&((x|y|z)>1?3:7):P&&(P=="if"?M`(`&E()&M`)`+M():7)&J()&(A[R]|1)&M`=`&E()&M`;`&S(++x)
Q=_=>M()||J(A={})&(L[F=R]&5?1:7)&M`(`&O(_=>J(M())&(A[R]|(L[R]|=1)&6?1:A[R]=7),x=y=z=0)&M`{`&S()&Q(L[F]=6)
f=c=>Math.log2(Q(U={},L={},i=0,I=c.match(/\w+|\S/g)||[])+1)

```

Try it online! (comes with test cases)

Defines a function `f` that takes the code as argument.

### Explanation

This monstrosity is essentially a huge recursive bitwise AND, which somehow happens to work as a parser for this C subset. Scores are stored as `0137` for `0123` respectively and converted in the end as `log2(score+1)`; if any phase detects a problem in the code, it returns a score lower than 7, which in turn unsets bits from the final output and results in a lower score. All functions return a score.

If the code runs out of input, it will just continue happily reading `undefined`s from the token array. This is fine, since the only function that matches `undefined` is `J`, and anything will eventually finish recursing and return 0 due to not matching a closing `}`. (Except for `S` and `Q` which have explicit checks for end of input.)

```
// Globals:
//   I = input tokens
//   i = input position
//   P = last token consumed
//   R = last identifier consumed
//   x,y,z = number of assignments, binary ops, func calls
//   A = current function args
//   F = current function name
//   L = used identifiers as bitfields: 1=argument, 2=call, 4=definition
//   U = function arg counts

// M(p): Consume a token, store it in P, return 7 if P == p, otherwise false (0).
M = p => (P = I[i++]) == p && 7
// J(): Copy P to R, return 7 if valid identifier, otherwise 0.
J = _ => /^[a-z]+$/.test(R = P) * 7
// O(Z, 0): Parse args for R() using the function Z.
O = (Z, a, n = R) =>  // a = arg count, n = name of function (for nested calls)
  M`)` ?              // consume token, is it ")"?
    (L[n] |= 2)         // if yes, mark n() as a called function
    & 1                 // and see if n has been used as an arg
    | U[n] - (U[n] = a) // see if n() already has a different arg count, store new count
    ? 1 : 7             // if yes to either, cap score at 1
  :                   // token wasn't ")"
    (a++                // increment arg count, is this first arg?
    ? P == ","            // if not, truthy only if token was ","
    : i--)                // else, push token back & be truthy
    && Z()              // if truthy, parse the actual arg
    & O(Z,a,n)          // and recurse
// E(): Parse expression.
E = _ =>
                      // first, parse a primary expression:
  (M`(`                 // consume token, is it "("?
  ? E() & M`)`            // if yes, parse expr + ")"
  : P-~P ?              // else, is it numeric?
  7                       // if yes, it's a valid primary expr
  :                     // else,
  J() &                   // parse identifier into R
  (M`(`                   // consume token, is it "("?
  ? O(E, !++z)              // if yes, parse args for R()
  : A[i--, R] | 1)          // else, push token back and see if R is a valid variable
  ) & (               // now, handle infix operators:
  /[+*/%-]/.test(I[i])  // is the next token an operator?
  ? E(++y + i++)          // if yes, consume & parse another expr
  : 7)                    // else, we're done

// S(): Parse statement.
S = _ =>
  M`return` ?                // consume token, is it "return"?
  E() & M`;` & M`}`            // if yes, parse expr + expect ";}"
  & ((x | y | z) > 1 ? 3 : 7)  // and check modularity
  : P &&                     // else, if EOF, return undefined
  (P == "if"                 // else, is it "if"?
  ? M`(` & E() & M`)`          // if yes, parse "(" + expr + ")"
  + M()                        // and consume another token to P
  :                          // else,
  7)                           // just a normal assignment
  & J()                      // parse identifier into R
  & (A[R] | 1)               // check if R is a valid variable
  & M`=` & E() & M`;`        // parse "=" + expr + ";"
  & S(++x)                   // parse next statement

// Q(): Parse function.
Q = _ =>
  M() ||          // consume token, return undefined if EOF
  J(A = {})       // parse identifier into R
  & (L[F = R] & 5 ? 1 : 7)  // see if it's been used as arg or defined
  & M`(`          // expect "("
  & O(_ =>        // parse arg list with O(), name parsing func:
    J(M()) &        // consume & parse identifier into R
    (A[R] |         // see if R is already in this func's args
    (L[R] |= 1)     // mark R as a used arg name
    & 6             // see if R() is a called or defined func
    ? 1             // if yes to either, cap score to 1
    : A[R] = 7),    // else, add R to this func's args
  x = y = z = 0)  // reset modularity counters
  & M`{` & S()    // parse "{" + statement(s)
  & Q(L[F] = 6)   // parse next function, mark F() as defined

// f(c): Parse & score code c.
f = c =>
  Math.log2(Q(
    U = {}, L = {}, i = 0,
    I = c.match(/\w+|\S/g) || [])  // C lexer (:D)
  + 1)

```

Some of my favorites:

* `(L[n]|=2)&1|U[n]-(U[n]=a)?1:7` simultaneously exploits `undefined`, `NaN` and left-to-right evaluation order
* There turned out to be a shorter "is numeric" check than `x==+x`, when used only as truthy/falsy: `x-~x`.
> 12 votes

---
Tags: code-golf, parsing, c
---


title: Measuring Mountains

text:
# Question
Title: Measuring Mountains
Sum-It is a language I created (quite late) for the Language Design Contest in TNB, for which the theme was "Range". Naturally I interpreted this as "Mountain Range" and created a language about mountains.

Sum-It code takes the form of several ASCII art mountains, using only the `/` and `\` characters. The mountains are then parsed to a number representing the size of the mountain, and that number is used as either an opcode or a data value.

While developing the parser for this language, I noticed something quite interesting regarding mountain sizes:

The size of a standalone (ie: not overlapped) mountain is equivalent to double the sum of all integers lower than the mountain's height in characters.

So for example, the following mountain:

```
  /\   <- 1
 /  \  <- 2
/    \ <- 3

```

Has a character height of 3. Its "size" as far as Sum-It is concerned, is calculated as such:

```
  /\
 /##\
/####\

```

And is therefore 6.
This lines up with the above formula, because the sum of all integers lower than 3 is `1 + 2 = 3`, which doubled is 6.

## The challenge

Your challenge is, given a positive integer representing a mountain's height, output the Sum-It size of the mountain, using the above formula.

## Scoring

This is , so fewest bytes wins!

## Test Cases

Test cases are represented as `input => output => formula`

```
1 => 0 => 2()
2 => 2 => 2(1)
3 => 6 => 2(1+2)
4 => 12 => 2(1+2+3)
5 => 20 => 2(1+2+3+4)
6 => 30 => 2(1+2+3+4+5)
7 => 42 => 2(1+2+3+4+5+6)
8 => 56 => 2(1+2+3+4+5+6+7)
9 => 72 => 2(1+2+3+4+5+6+7+8)
10 => 90 => 2(1+2+3+4+5+6+7+8+9)
15 => 210 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14)
20 => 380 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19)
25 => 600 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24)
30 => 870 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29)
40 => 1560 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39)
50 => 2450 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49)
60 => 3540 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59)
70 => 4830 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69)
80 => 6320 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79)
90 => 8010 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89)
100 => 9900 => 2(1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99)

```

# Answer
> 1 votes
# APL+WIN, ~~8~~ 6 bytes

```
+/2×⍳⎕

```

Prompts for input integer, creates a vector of integers from 1 to integer -1, multiplies by 2 and sums the result.

Saved 2 bytes thanks to Adam by switching to index origin zero.

# Answer
> 0 votes
# C (gcc), 31 bytes

```
i;f(n,a){for(;--n;i+=n);a=i*2;}

```

Try it online!

EDIT: By using a global variable multiple execution of the functions wil lget wrong results. I'm not sure wether that's ok or no. Pretty new to PPCG.

Here's the corrected version:

# C (gcc), 34 bytes

```
f(n,i,a){for(i=0;--n;i+=n);a=i*2;}

```

Try it online!

# Answer
> 0 votes
# Japt `-mx`, 1 bytes

```
Ñ

```

`-m` implicity flag creates a range from `0` to `input - 1`

`Ñ` multiply each value in the range by 2

Flag `-x` implicity outputs the sum of the result

Try it online!

# Answer
> 0 votes
# C (gcc), 13 bytes

```
f(x){x*=x--;}

```

Try it online!

# Answer
> 0 votes
# Haskell, 10 bytes

```
(*)=<<pred

```

Try it online, using `(<*>)` would work too since multiplication is commutative..

## Alternative, 9 bytes

I'm not completely sure if this is allowed, according to this I believe it is:

```
id<>(-1+)

```

Takes input as `Product` type, try it online!

# Answer
> 0 votes
# Catholicon, 2 bytes

```
*Ẏ

```

Explanation:

```
*    multiply (the implicit input)
 Ẏ   by the implicit input decremented

```

---
Tags: code-golf, arithmetic
---


title: Color of a Pixel

text:
# Question
Title: Color of a Pixel
Write a program that prints the RGB color of a given pixel on the screen.

The program should read a line from stdin in the format `x,y`, where x and y are unsigned integers. The pixel (0,0) is the top left pixel in the screen.

The program should then output a line to stdout in the format `RRR,GGG,BBB`, which represents the color of the pixel at (`x`,`y`).

`RRR`, `GGG`, and `BBB` should be floating-point numbers between 0 and 1, **OR** integers in the range \[0, 255\]. Leading zeros do not matter, for example: both `074` and `74` are acceptable.

**Undefined Behavior**

It is okay for the program to exhibit undefined behavior (crash, give incorrect output, etc) in the following conditions:

* The user inputs a string, signed integer, float, or any other invalid data type
* The user input is not in the format `x,y`
* The specified pixel is off-screen

**Notes:**

* The program cannot modify the pixel at the given coordinates.
* If you have multiple monitors, it does not matter which monitor the pixel is on, as long as the same monitor is used each time the program runs.

The answer with the fewest bytes wins.

# Answer
> 10 votes
# Java 10 (lambda function), ~~105~~ 75 bytes

```
x->y->(new java.awt.Robot().getPixelColor(x,y)+"").replaceAll("[^\\d,]","")

```

A function taking two integer parameters and returning a String `RRR,GGG,BBB`, where the colors are integers in the range `[0, 255]`.

-30 bytes thanks to *@LukeStevens* by using `java.awt.Color`'s default `toString()` output and modifying it so only the digits and commas remain.

**Explanation:**

```
x->y->                      // Method with two integer parameters and String return-type
  (new java.awt.Robot()     //  Create a AWT-Robot instance
    .getPixelColor(x,y)     //  Get the pixel AWT-Color at position x,y
    +"")                    //  Call the default toString() of the AWT-Color
                            //   i.e. "java.awt.Color[r=213,g=230,b=245]"
  .replaceAll("[^\\d,]","") //  Remove everything except for digits and commas

```

NOTE: The default `toString()` implementation of the `java.awt.Color` has always been the same across JVM versions as far as I know, but can potentially change in the future. I tested it in both Java 8 and Java 10 and it returned `"java.awt.Color[r=#,g=#,b=#]"`.

---

But, since the challenge states:

* Full program
* Taking input in the format `x,y` from STDIN
* Output in the format `R,G,B` to STDOUT
* Have the `R`, `G`, `B` as floating points in the range `[0.0, 1.0]`

The code becomes A LOT more verbose:

# Java 10 (full program), 266 bytes

```
interface M{static void main(String[]a)throws Exception{var s=new java.util.Scanner(System.in).next().split(",");var c=new java.awt.Robot().getPixelColor(new Short(s[0]),new Short(s[1]));System.out.print(c.getRed()/255d+","+c.getGreen()/255d+","+c.getBlue()/255d);}}

```

**Explanation:**

```
interface M{          // Class
  static void main(String[]a)
                      //  Mandatory main method
    throws Exception{ //    Mandatory throws clause for `new Robot()`
  var s=new java.util.Scanner(System.in)
                      //   Create a Scanner for STDIN
         .next()      //   Get the String user input
         .split(","); //   Split it on "," and save it as String-array in `s`
  var c=new java.awt.Robot()
                      //   Create a AWT-Robot instance
         .getPixelColor(
                      //   And get the pixel AWT-Color at position:
           new Short( //    Convert String to Short (and implicitly to int):
            s[0]),    //     x-coordinate input by user from String-array `s`
           new Short( //    Convert String to Short (and implicitly to int):
            s[1]));   //     y-coordinate input by user from String-array `s`
  System.out.print(   //   Print to STDOUT:
   c.getRed()         //    The red part of RGB as integer in the range [0,255]
    /255d             //     Converted to a floating point in the range [0.0, 1.0]
   +","               //    Appended with a comma delimiter
   +c.getGreen()      //    Appended with the green part of RGB as integer in the range [0,255]
     /255d            //     Converted to a floating point in the range [0.0, 1.0]
   +","               //    Appended with a comma delimiter
   +c.getBlue()       //    Appended with the blue part of RGB as integer in the range [0,255]
     /255d);}}        //     Converted to a floating point in the range [0.0, 1.0]

```

# Answer
> 10 votes
# 6502 machine code (C64), 280 260 bytes

```
00 C0 A2 00 20 CF FF C9 0D 9D 02 C1 F0 03 E8 D0 F3 20 D2 FF A5 7A 85 FB A5 7B
85 FC A9 01 85 7A A9 C1 85 7B 20 73 00 20 6B A9 A5 14 85 FD A5 15 85 FE 20 73
00 20 6B A9 A5 FB 85 7A A5 FC 85 7B A5 14 4A 4A 4A AA 20 F0 E9 A5 FD 46 FE 6A
4A 4A A8 A5 14 29 07 AA A9 00 38 6A CA 10 FC 85 FE B1 D1 0A 26 FC 0A 26 FC 0A
26 FC 85 FB A5 D2 29 03 09 D8 85 D2 B1 D1 85 02 A9 02 18 2D 18 D0 0A 0A 65 FC
29 0F 09 D0 85 FC A9 33 85 01 A5 FD 29 07 A8 B1 FB A2 37 86 01 25 FE D0 05 AD
21 D0 85 02 A6 D6 20 F0 E9 A5 02 29 0F AA BC D2 C0 20 BC C0 BC E2 C0 20 B7 C0
BC F2 C0 A9 2C 20 D2 FF 98 0A A9 30 90 02 A9 31 20 D2 FF A9 2E 20 D2 FF 98 29
7F 4C D2 FF 30 B0 35 35 36 33 32 39 36 33 38 33 35 37 34 37 30 B0 32 38 32 37
32 39 33 32 34 33 35 B0 34 37 30 B0 32 38 36 33 36 34 32 30 34 33 35 36 39 37

```

I expected this to be possible in a lot fewer bytes, but unfortunately... well, since I finished it, posting it now anyways. At least, the restrictive format helped with one thing: Something similar to `stdin` (input from a current device) only exists on the C64 in text mode, because the OS only supports this mode -- so no need to consider other modes of the graphics chip.

Note on the output of the color values: the C64 graphics chip doesn't use RGB colors but directly generates a video signal with YUV colors, with a fixed 16 colors palette. I used rounded values of the colodore conversion to RGB with "default" monitor settings here.

**-20 bytes**: better output routine, encoding the 3 character output per color channel in a single byte.

Regarding the comment: It's theoretically possible to use even multicolor character mode of the VIC with the stock C64 OS, but it requires a custom font that's actually legible with only 4 horizontal pixels of doubled width. Not entirely impossible, but very unlikely. Likewise, extended color mode (or extended background mode, which is the same) *could* be used with the C64 OS, but requires to reconfigure the graphics chip directly. I opt to ignore all these possibilities in the sense of code golfing here: It's not the standard environment you find on a Commodore 64 with running stock OS. What's possible with stock OS is switching between two builtin fonts (shift + commodore key), the program does account for that.

### Online demo

Usage: `SYS49152` to start.

**Commented disassembly**:

```
         00 C0       .WORD $C000        ; load address
.C:c000  A2 00       LDX #$00           ; loop index for input
.C:c002   .input:
.C:c002  20 CF FF    JSR $FFCF          ; character from input device
.C:c005  C9 0D       CMP #$0D           ; compare with enter
.C:c007  9D 16 C1    STA .buf,X         ; store to buffer
.C:c00a  F0 03       BEQ .parse         ; was enter -> start parsing
.C:c00c  E8          INX                ; next character
.C:c00d  D0 F3       BNE .input         ; and repeat input loop
.C:c00f   .parse:
.C:c00f  20 D2 FF    JSR $FFD2          ; output the enter character
.C:c012  A5 7A       LDA $7A            ; save pointer of BASIC parser
.C:c014  85 FB       STA $FB
.C:c016  A5 7B       LDA $7B
.C:c018  85 FC       STA $FC
.C:c01a  A9 15       LDA #$15           ; set pointer of BASIC parser to
.C:c01c  85 7A       STA $7A            ; buffer-1
.C:c01e  A9 C1       LDA #$C1
.C:c020  85 7B       STA $7B
.C:c022  20 73 00    JSR $0073          ; get next character
.C:c025  20 6B A9    JSR $A96B          ; BASIC routine to parse number
.C:c028  A5 14       LDA $14            ; lowbyte of parsed number to $fd
.C:c02a  85 FD       STA $FD
.C:c02c  A5 15       LDA $15            ; highbyte to $fe
.C:c02e  85 FE       STA $FE
.C:c030  20 73 00    JSR $0073          ; get next character
.C:c033  20 6B A9    JSR $A96B          ; parse as number ...
.C:c036  A5 FB       LDA $FB            ; restore pointer of BASIC parser
.C:c038  85 7A       STA $7A
.C:c03a  A5 FC       LDA $FC
.C:c03c  85 7B       STA $7B
.C:c03e  A5 14       LDA $14            ; load y coordinate
.C:c040  4A          LSR A              ; divide by 8 for character row
.C:c041  4A          LSR A
.C:c042  4A          LSR A
.C:c043  AA          TAX                ; -> to X
.C:c044  20 F0 E9    JSR $E9F0          ; set pointer to character row
.C:c047  A5 FD       LDA $FD            ; divide x coordinate by 8
.C:c049  46 FE       LSR $FE
.C:c04b  6A          ROR A
.C:c04c  4A          LSR A
.C:c04d  4A          LSR A
.C:c04e  A8          TAY                ; -> to Y
.C:c04f  A5 14       LDA $14            ; load y coordinate
.C:c051  29 07       AND #$07           ; mask pixel position in character
.C:c053  AA          TAX                ; -> to X
.C:c054  A9 00       LDA #$00           ; initialize pixel mask to 0
.C:c056  38          SEC                ; set carry for bit to shift in
.C:c057   .bitnum:
.C:c057  6A          ROR A              ; shift bit in mask
.C:c058  CA          DEX                ; and repeat until
.C:c059  10 FC       BPL .bitnum        ; in correct position
.C:c05b  85 FE       STA $FE            ; store pixel mask to $fe
.C:c05d  B1 D1       LDA ($D1),Y        ; load character code
.C:c05f  0A          ASL A              ; multiply by 8
.C:c060  26 FC       ROL $FC
.C:c062  0A          ASL A
.C:c063  26 FC       ROL $FC
.C:c065  0A          ASL A
.C:c066  26 FC       ROL $FC
.C:c068  85 FB       STA $FB            ; and store to $fb/$fc
.C:c06a  A5 D2       LDA $D2            ; move pointer to position in color RAM
.C:c06c  29 03       AND #$03
.C:c06e  09 D8       ORA #$D8
.C:c070  85 D2       STA $D2
.C:c072  B1 D1       LDA ($D1),Y        ; load color of character
.C:c074  85 02       STA $02            ; and store to $2
.C:c076  A9 02       LDA #$02           ; check which charset is active
.C:c078  18          CLC
.C:c079  2D 18 D0    AND $D018
.C:c07c  0A          ASL A              ; and calculate offset
.C:c07d  0A          ASL A
.C:c07e  65 FC       ADC $FC            ; add to (character code * 8)
.C:c080  29 0F       AND #$0F
.C:c082  09 D0       ORA #$D0           ; and add offset to character ROM
.C:c084  85 FC       STA $FC
.C:c086  A9 33       LDA #$33           ; bank in character ROM
.C:c088  85 01       STA $01
.C:c08a  A5 FD       LDA $FD            ; load y coordinate
.C:c08c  29 07       AND #$07           ; mask pixel-row number
.C:c08e  A8          TAY
.C:c08f  B1 FB       LDA ($FB),Y        ; load pixel row from character ROM
.C:c091  A2 37       LDX #$37           ; bank out character ROM
.C:c093  86 01       STX $01
.C:c095  25 FE       AND $FE            ; apply pixel mask
.C:c097  D0 05       BNE .pixelcol      ; not 0 -> pixel is set
.C:c099  AD 21 D0    LDA $D021          ; otherwise load background color
.C:c09c  85 02       STA $02            ; and store to $2
.C:c09e   .pixelcol:
.C:c09e  A6 D6       LDX $D6            ; restore screen row pointer for
.C:c0a0  20 F0 E9    JSR $E9F0          ; current cursor position
.C:c0a3  A5 02       LDA $02            ; load color
.C:c0a5  29 0F       AND #$0F           ; mask low nibble (only 16 colors)
.C:c0a7  AA          TAX                ; -> to X
.C:c0a8  BC D2 C0    LDY .red,X         ; load encoded output for red
.C:c0ab  20 BC C0    JSR .out2          ; call output without comma
.C:c0ae  BC E2 C0    LDY .green,X       ; load encoded output for green
.C:c0b1  20 B7 C0    JSR .out1          ; call output with comma
.C:c0b4  BC F2 C0    LDY .blue,X        ; load encoded output for blue
.C:c0b7   .out1:
.C:c0b7  A9 2C       LDA #$2C           ; load ","
.C:c0b9  20 D2 FF    JSR $FFD2          ; and output
.C:c0bc   .out2:
.C:c0bc  98          TYA                ; encoded output to A
.C:c0bd  0A          ASL A              ; shift top bit to carry
.C:c0be  A9 30       LDA #$30           ; load "0"
.C:c0c0  90 02       BCC .firstdig      ; carry clear -> to output
.C:c0c2  A9 31       LDA #$31           ; load "1"
.C:c0c4   .firstdig:
.C:c0c4  20 D2 FF    JSR $FFD2          ; and output
.C:c0c7  A9 2E       LDA #$2E           ; load "."
.C:c0c9  20 D2 FF    JSR $FFD2          ; and output
.C:c0cc  98          TYA                ; encoded output to A
.C:c0cd  29 7F       AND #$7F           ; mask out top bit
.C:c0cf  4C D2 FF    JMP $FFD2          ; to output and exit
.C:c0d2   .red:                                 ; encoded values for red
.C:c0d2  30 B0 35 35 .BYTE $30,$B0,$35,$35      ; ASCII digit ($30-$39) after
.C:c0d6  36 33 32 39 .BYTE $36,$33,$32,$39      ; decimal point, with bit 7
.C:c0da  36 33 38 33 .BYTE $36,$33,$38,$33      ; indicating 0 or 1 before
.C:c0de  35 37 34 37 .BYTE $35,$37,$34,$37      ; decimal point
.C:c0e2   .green:                               ; encoded values for green
.C:c0e2  30 B0 32 38 .BYTE $30,$B0,$32,$38      ; ...
.C:c0e6  32 37 32 39 .BYTE $32,$37,$32,$39
.C:c0ea  33 32 34 33 .BYTE $33,$32,$34,$33
.C:c0ee  35 B0 34 37 .BYTE $35,$B0,$34,$37
.C:c0f2   .blue:                                ; encoded values for blue
.C:c0f2  30 B0 32 38 .BYTE $30,$B0,$32,$38      ; ...
.C:c0f6  36 33 36 34 .BYTE $36,$33,$36,$34
.C:c0fa  32 30 34 33 .BYTE $32,$30,$34,$33
.C:c0fe  35 36 39 37 .BYTE $35,$36,$39,$37
.C:c102   .buf:                                 ; buffer for input ("stdin")

```

# Answer
> 6 votes
# TI-BASIC (TI-83/84+), 22 bytes

Since the screen is black and white, we just need to test if the specified pixel is on or off and map that to black or white RGB. Also, the pixels are only accessible through row and column in that order, so that's why the coordinates are reversed.

```
Prompt X,Y
255
Ans-{Ans,Ans,Ans}pxl-Test(Y,X

```

# Answer
> 2 votes
## bash, 103 / 86 bytes

With a strict interpretation of the spec (input from STDIN and output on STDOUT are both comma-separated):

```
read x
import -window root -crop 1x1+${x/,/+} ppm:-|od -dj13|awk 'NR<2{n=2^16;print$2/n","$3/n","$4/n}'

```

With a looser input format (plus-separated input as a command line argument, space-separated output:

```
import -window root -crop 1x1+$1 ppm:-|od -dj13|awk 'NR<2{n=2^16;print$2/n,$3/n,$4/n}'

```

Depends on imagemagick, awk, and coreutils.

# Answer
> 2 votes
# TI-Nspire assembly - 112 bytes

```
50 52 47 00 30 40 2D E9 FF FF FF FA 00 F0 17 F8
04 1C 00 F0 14 F8 85 00 2D 18 AD 01 2D 19 6C 00
C0 21 09 06 09 69 08 5B 3F 25 42 09 2A 40 1F 25
03 1C 2B 40 C1 0A 29 40 0A A0 0A DF 30 BD 00 20
0A 23 07 49 10 25 8A 69 2A 42 FC D1 0A 68 FF 25
2A 40 30 3A 0B DB 85 00 2D 18 6D 00 A8 18 F1 E7
00 00 02 90 25 64 2C 25 64 2C 25 64 0A 00 70 47

```

This program outputs integers in the range 0-31 for R and B and 0-63 for G, because the device natively uses a RGB565 framebuffer. It uses serial for input and output.

## Source:

```
.string "PRG"
push {r4, r5, lr}
blx main
.thumb
main:
@ read x and y from serial into r4 and r0
bl read_int
mov r4, r0
bl read_int

@ turn x and y into framebuffer offset
@ r4 = ((r0 * 320) + r4) * 2
lsl r5, r0, #2
add r5, r0
lsl r5, #6
add r5, r4
lsl r4, r5, #1

@ load pixel from framebuffer
@ r0 = ((uint16_t **)0xc0000000)[0x10][r4 / 2]
mov r1, #0xC0
lsl r1, #24
ldr r1, [r1, #0x10]
ldrh r0, [r1, r4]

@ unpack RGB565 value into r1, r2, r3
mov r5, #0x3f
lsr r2, r0, #5
and r2, r5
mov r5, #0x1f
mov r3, r0
and r3, r5
lsr r1, r0, #11
and r1, r5

@ call printf
adr r0, fmt
swi #10

@ return
pop {r4, r5, pc}

@ subroutine to read an integer from serial
read_int:
mov r0, #0
mov r3, #10
ldr r1, serial_base
@ loop until characters come in on serial
2:
mov r5, #(1<<4)
1:
ldr r2, [r1, #0x18]
tst r2, r5
bne 1b
@ read character from serial and mask out status bits
ldr r2, [r1]
mov r5, #0xff
and r2, r5
@ subtract 48 ('0') from byte; if result is negative, return
sub r2, #48
blt 1f
@ multiply existing numbers by 10 and add new number to them
lsl r5, r0, #2
add r5, r0
lsl r5, #1
add r0, r5, r2
b 2b

serial_base:.word 0x90020000
fmt:.string "%d,%d,%d\n"
@ this instruction is over here because serial_base and fmt need to be word-aligned
1:bx lr

```

# Answer
> 1 votes
# Python 2 \+ PIL library, ~~96~~ 91 bytes

```
import PIL.ImageGrab as i
print','.join('%.1f'%(x/255.)for x in i.grab().getpixel(input()))

```

Implements the specification literally as requested. Windows only though - doesn't work on Linux, and produces extra output (alpha value) on Mac.

# Answer
> 1 votes
## Mathematica, 69 Bytes

Just the function is 34 bytes.

`CurrentScreenImage[]~PixelValue~#&`

Takes input in the form {x,y}.

The image is the merging of images on all monitors. If you want a particular screen, use the integer index - e.g. `CurrentScreenImage[1]`

Full program exactly as specified is 69 Bytes `CurrentScreenImage[]~PixelValue~ToExpression["{"<>InputString[]<>"}"]`

# Answer
> 1 votes
# AutoHotKey, 113 bytes

```
CoordMode,Pixel
InputBox,x
InputBox,y
PixelGetColor,c,x,y
MsgBox % c&255 . "," . c>>8&255 . "," . c>>16&255

```

Use dialog boxes instead of stdin/stdout.

# Answer
> 1 votes
# Bash on Linux with xserver, 30 bytes

```
xset dpms force off;echo 0,0,0

```

Using the idea presented in my comment on the question, this solution should turn off the display output completely, and then echo that the screen is indeed black.

I was also thinking of using `xbacklight =0`, but that doesn't change the pixel colors.

# Answer
> 0 votes
# Bash + coreutils + scrot + netpbm, 90 bytes

```
scrot -e'pngtopnm $f'|(read a;read w h;read m;head -c$((3*(w*$2+$1)))>f;od -t u1 -N3 -An;)
```

Loose I/O version

Takes `x` and `y` as separate command-line arguments.

Prints `r`, `g`, `b` as ints from 0-255 on separate lines

---

# Bash + coreutils + scrot + netpbm + bc + sed, 172 bytes

```
IFS=, read x y
scrot -e'pngtopnm $f'|(read a;read w h;read m;head -c$((3*(w*$y+$x)))>f;od -vw1 -tu1 -N3 -An|while read p;do bc<<<"scale=2;$p/$m"|tr '\n' ,;done;)|sed s/,$//
```

Strict I/O version

Input on stdin as `x,y`

Output on stdout as `r.rr,g.gg,b.bb` (no newline).

# Answer
> 0 votes
# TI-BASIC (TI-83/84+), 15 bytes

```
Input Y
255not(rand(3)pxl-Test(Y,Ans

```

Takes one integer from `Ans` and one from the prompt. `rand(3)` creates a list of 3 nonzero random numbers, so the product is zero iff the pixel is dark.

---
Tags: code-golf, color
---